【问题标题】:How do I access my angular controller when handling a browser 'full screen' event?处理浏览器“全屏”事件时如何访问我的角度控制器?
【发布时间】:2017-09-26 00:22:24
【问题描述】:

在我的角度控制器(这是一个用于 Google 地图指令的控制器)中,我正在像这样在文档元素上添加一个事件监听器,因此我可以使用全屏 API:

        if (document.addEventListener) {
            document.addEventListener("webkitfullscreenchange", this.fullScreenChangeHandler, false);
            document.addEventListener("mozfullscreenchange", this.fullScreenChangeHandler, false);
            document.addEventListener("fullscreenchange", this.fullScreenChangeHandler, false);
            document.addEventListener("MSFullscreenChange", this.fullScreenChangeHandler, false);
        }

然后我在我的 fullScreenChangeHandler 方法中处理这样的事件,该方法也直接位于控制器中:

    fullScreenChangeHandler(event) {

        var containerScope = angular.element(event.srcElement).scope();
        var map = containerScope.map;
        var mapController = containerScope.$parent.mapsCtrl;

So (event.srcElement) = 文档节点。这种访问控制器的方法有效,但不知何故坏了。无论如何,感觉代码很臭,所以一定有更好的办法。我会很感激任何有关方向的建议。

【问题讨论】:

  • 为什么需要访问 mapsCtrl?
  • 我正在实现自定义的“最大化地图”和“恢复地图”按钮,而不是谷歌地图的默认按钮,当使用“esc”时,“fullScreenChangeHandler”需要进行地图居中和重新绘制退出全屏模式。 (我需要自定义样式以及按钮的自定义功能,这就是我不使用默认值的原因)

标签: javascript angularjs events controller


【解决方案1】:

我认为还有其他两种方法可以实现您的功能。

1) 使用 $rootScope 触发“fullscreenchange”并在您的控制器上监听事件:

// inside fullScreenChangeHandler
// inject $rootScope 
var $body = angular.element(document.body);           
var $rootScope = $bodyF.injector().get('$rootScope');  
$rootScope.broadcast('FULL_SIZE_CHANGED');

使用 $scope.on('FULL_SIZE_CHANGED',...) 在 MapController 上正常监听事件

2) 在 MapController 中编写事件处理程序。

//inside MapController
angular.element($window).on('fullscreenchange', fullScreenChangeHandler);

fullScreenChangeHandler(evt){
    //call resize map here
    scope.resizeMap()
    ...
    // you need $scope.$apply to notify angular about the changes because this event outside of angular context:
    $scope.$apply();
}

我不喜欢 rootScope,如果你只有一个监听器,我更喜欢第二个。

【讨论】:

  • 代码是用map controller写的,为什么scope不可用
  • 谢谢 Vu,你的第二个建议很有趣。 fullscreenchange 或等效事件(在浏览器之间有所不同)发生在文档而不是窗口上(如果我们在 angular 对象上注册事件,我会认为我们可能不需要 $scope.$apply,尽管我'对此并不完全确定)。在实际的事件处理函数(fullScreenChangeHandler)中,我无论如何都无法使用 $scope - 在地图退出时,可以使用文档节点作为源来接收事件,这意味着 angular 不知道我想要哪个 $scope访问
  • +1 对于广播到 $rootScope 的第一个建议,我认为这可能是要走的路,尽管我还没有测试过。不过,为了避免污染 rootScope,“mapFullSizeChanged”的特定事件会更好。
  • 重要的是您可以直接在您的事件处理程序中调用 MapController 的方法,例如 scope.resizeMap();
【解决方案2】:

我发现进入全屏时,fullscreenchange 事件接收到的源元素是我的指令模板中的一个容器 div,所以按照我的方式引用控制器仍然有效。

问题仅在关闭地图时出现,在这种情况下,事件接收到的 srcElement 是文档节点。在退出的情况下,我不需要访问地图。

所以,我可以检查我是否正在进入全屏模式并获得这样的控制器:

        var containerScope;
        var mapController;

        if (event.srcElement.id) {
            if (event.srcElement.id.indexOf("myMapContainer") != -1) {
                containerScope = angular.element(event.srcElement).scope();
                mapController = containerScope.$parent.mapsCtrl;
            }
        }

只有当我可以访问控制器时,我才能进行地图居中:

        if (mapController) {
           .... center and resize the map
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多