在工厂中创建新的隔离范围的问题

时间:2015-01-13 15:16:56

标签: angularjs angularjs-scope angularjs-service

我想通过$rootScope.$new()

了解在工厂中创建新隔离范围的后果/问题是什么

我试图允许我的库的用户执行$cordovaPush.$on('notReceived')之类的操作,而不是使用$rootScope.$on('...')(尽管这样做可能毫无意义)。我已经看到了关于内存泄漏的其他评论以及创建新范围的各种其他问题,但我还没有找到任何证据或真正有说服力的论据,说明为什么不应该这样做。

这里有一些代码作为我正在做的事情的参考:

.factory('$cordovaPush', ['$q', '$window', '$rootScope', '$timeout', function ($q, $window, $rootScope, $timeout) {

  var $cordovaPush = $rootScope.$new(true);

  $cordovaPush.onNotification = function (notification) {
    $timeout(function () {
      $cordovaPush.$broadcast('notificationReceived', notification);
    });
  };
  $cordovaPush.register = function (config) {
    ...
  };
  $cordovaPush.unregister = function (options) {
    ...
  };
  $cordovaPush.setBadgeNumber = function (number) {
    ...
  };

  return $cordovaPush;
}]);

ALSO

如果创建新范围可以,那么销毁范围的最佳做法是什么?如果应用程序关闭并再次打开,是否有必要销毁范围?

1 个答案:

答案 0 :(得分:0)

不,我不认为你应该这样做。

您正在创建一个未绑定到DOM元素的范围对象,除非通过代码手动完成,否则它将永远不会被销毁,唯一的好处是拥有$on方法。 如果我正确地阅读了您的问题。

$cordovaPush.$broadcast('notificationReceived', notification);

这个广播的儿童范围是什么?这是手册中的剪辑

  

$ broadcast :将事件名称向下调度到所有子范围(及其子级),通知已注册的$ rootScope.Scope侦听器。

由于范围不是DOM层次结构的一部分。除非您手动创建子项,否则不太可能创建任何子项。

  

我试图允许我的图书馆用户执行$ cordovaPush。$ on(' notReceived'),而不是使用$ rootScope。$ on('。 ..')(即使这样做可能毫无意义)。

你试图混合两种不同的东西。

  1. $cordovaPush
  2. 的特定对象
  3. 向所有儿童播放的非特定事件。
  4. 我想知道factory是否适合您尝试做的事情。如果我正在使用类似的API,我将使用指令和控制器。

    这是我要做的一个例子。

    var app = angular.module('myApp',[]);
    
    app.directive('cordovaPush',function() {
        return {
            controller: function($scope) {
                this.register = function(config) {
                    // ...
                };
                this.unregister = function(options) {
                    // ...
                };
                this.setBadgeNumber = function(number) {
                    // maybe this needs to broadcast? here's an example
                    $scope.$broadcast('notificationReceived');
                };
            },
            link: function($scope, $el, $attr, ctrl) {
                // you can inject options from the DOM attributes to the controller
                ctrl.setBadgeNumber($attr['badgeNumber'] || 0);
            }
        }
    });
    
    // here is a directive that works with the above
    app.directive('myStuff',function() {
        return {
           require: '^cordovaPush',
           link: function($scope, $el, $attr, cordovaPush) {
              $scope.$on('notReceived',function() {
                  // ...
              });
              cordovaPush.register({});
              cordovaPush.setBadgeNumber(2);
           }
    });
    
相关问题