孤立的$ firebase引用导致内存泄漏

时间:2014-08-28 17:11:33

标签: angularjs firebase angularfire

我有一个角度服务,可以创建同步的$ firebase引用。这些引用最终传递到控制器,然后传递给具有隔离范围的指令。

当通过导航到另一个状态来销毁控制器的$ scope时,引用似乎保留在内存中并且永远不会被GCed。

代码示例:

var app = angular.module('app', ['firebase', 'ui.router']);

app.service('service', function($firebase) {

  var ref = new Firebase('https://ease-bugreport.firebaseio.com/tasks');

  return {
    find: function(taskId) {
      // Creating orphan refs after states are changed. Not getting $destroy()-ed as the corresponding scope is destroyed?
      return $firebase(ref.child(taskId)).$asObject();
    }
  }

});

app.controller('ctrl', function($scope, service) {

  $scope.tasks = [];

  /*
      * In the real application, this list of ids is grabbed from an index of ids.
      */
  var taskIds = [
    '-JVMmByyk5wvYdVJQ_JT',
    '-JVMmBz4hue-5QytQwWb',
    '-JVMmBz8aAt5WDUQ4H1R',
    '-JVMmC-Q8QEGB6zZuitb',
    '-JVMmC-UkMAiyi6v6bcK',
    '-JVMmC-WyOrlNKZTjnqH',
    '-JVMmC-Y29ncf14G1rkA',
    '-JVMmC0coVLi1FUfrbKD',
    '-JVMmC1hDrs07XdwcgLh',
    '-JVMmC1k-GYz_DWw3dDj',
    '-JVMmC2aCuzOIZ2nf1B-',
    '-JVMmC2cQKNkOBxhJ5vP',
    '-JVMmC2giV_IlXrKXVFw',
    '-JVMmC3fXQYfjtXdTk_p',
    '-JVMmC3ibcUPT88hcD6Q',
    '-JVMmC3mDKms0BVpAcdq',
    '-JVMmC4jFwfPNe1-istd',
    '-JVMmC4m3ZGAiS7xnXHP',
    '-JVMmC4rp3pNfeTgIUCJ',
    '-JVMmC4uaH7MdkTZbQVm',
    '-JVMmC5ttFy3ojD1bt3t',
    '-JVMmC5v_iTwWS02PF9h',
    '-JVMmC5xFYPS0zvaU4bi',
    '-JVMmC75NA1H1e7dYGdM',
    '-JVMmC77o5mBUACibaUG',
    '-JVMmC7AmuYy6VDNn9B1',
    '-JVMmC85nVa6NexPJLLP',
    '-JVMmC88XIFUqq98gexw',
    '-JVMmC89h4HLaXxmHld8',
    '-JVMmC8CNJ55Olt8D57w'
  ];

  angular.forEach(taskIds, function(taskId) {
    $scope.tasks.push(service.find(taskId));
  });

});

app.directive('taskPanel', function() {
  return {
    scope: {
      task: '='
    },
    restrict: 'E',
    replace: true,
    template: '<div>{{task.name}} - {{task.createdAt | date}}</div>',
    link: function(scope, element, attrs) {

    }
  };

});

app.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider
  .state('main', {
    url: '/main',
    controller: function() {},
    template: '<div>MAIN PAGE!</div>'
  })
  .state('list', {
    url: '/list',
    controller: 'ctrl',
    templateUrl: 'list.html' 
  });

  $urlRouterProvider.otherwise('/main');

});

以下是展示此问题的规范: http://codepen.io/rabhw/pen/ADiKz

这个问题在我的应用程序中被夸大了,因为每个引用都使用了&#39; objectFactory&#39;通过工厂附加其他实例方法的选项。

我应该采取不同的方法来处理我的服务吗?

感谢任何建议。

1 个答案:

答案 0 :(得分:1)

尝试将以下代码添加到控制器:

$scope.$on('$destroy', function() {
    $scope.tasks = undefined; // or []
});

应该在指令task中自动识别。