将服务绑定到angular的$ rootScope是不是很糟糕?

lat*_*lip 32 javascript angularjs angularjs-rootscope

在角度,我有一个对象将通过服务暴露在我的应用程序中.

该对象上的某些字段是动态的,并且将通过使用该服务的控制器中的绑定正常更新.但是一些字段是计算属性,取决于其他字段,需要动态更新.

这里有一个简单的例子(这是工作在jsbin 这里).我的服务模型公开领域a,bc在那里c通过以下公式计算a + BcalcC().请注意,在我的实际应用程序中,计算要复杂得多,但实质内容就在这里.

我能想到让它工作的唯一方法是将我的服务模型绑定到$rootScope,然后$rootScope.$watch用来监视任何控制器更改ab何时更改,重新计算c.但这看起来很难看.有没有更好的方法呢?


第二个问题是表现.在我的整个应用程序ab是对象的大名单,其中获得合计下来c.这意味着$rootScope.$watch函数将进行大量深度数组检查,这听起来会损害性能.

我在BackBone中采用了一种平衡的方法,尽可能地减少了重新计算,但角度似乎并不适合采用一种方法.对此的任何想法都会很棒.


这是示例应用程序.

var myModule = angular.module('myModule', []);

//A service providing a model available to multiple controllers
myModule.factory('aModel', function($rootScope) {
  var myModel = {
    a: 10,
    b: 10,
    c: null
  };

  //compute c from a and b
  calcC = function() {
    myModel.c = parseInt(myModel.a, 10) * parseInt(myModel.b, 10);
  };

  $rootScope.myModel = myModel;
  $rootScope.$watch('myModel.a', calcC);
  $rootScope.$watch('myModel.b', calcC);

  return myModel;
});


myModule.controller('oneCtrl', function($scope, aModel) {
  $scope.aModel = aModel;
});

myModule.controller('twoCtrl', function($scope, aModel) {
  $scope.anotherModel = aModel;
});
Run Code Online (Sandbox Code Playgroud)

Ale*_*orn 7

虽然从较高的层面来看,我同意bmleite的回答($ rootScope存在使用,并且使用$ watch似乎适用于您的用例),我想提出一种替代方法.

使用$rootScope.$broadcast推变为$rootScope.$on听众,那么这将重新计算你的c价值.

这可以手动完成 - 即,当您主动更改ab值时,或者甚至可能在短暂的超时时间来限制更新的频率.更进一步的是在您的服务上创建一个"脏"标志,这样c只在需要时计算.

显然,这种方法意味着更多地参与控制器,指令等的重新计算 - 但如果你不想将更新绑定到每个可能的更改a或者b,那么问题就变成了"在哪里划线".


Jos*_*ler 2

一般来说,这可能不是一个好主意。(一般来说)将模型实现暴露给所有调用者也是不好的做法,如果没有其他原因,重构会变得更加困难和繁重。我们可以轻松解决这两个问题:

myModule.factory( 'aModel', function () {
  var myModel = { a: 10, b: 10 };

  return {
    get_a: function () { return myModel.a; },
    get_b: function () { return myModel.a; },
    get_c: function () { return myModel.a + myModel.b; }
  };
});
Run Code Online (Sandbox Code Playgroud)

这是最佳实践方法。它可扩展性良好,仅在需要时才被调用,并且不会污染$rootScope.

PS:您还可以在设置orc时进行更新,以避免每次调用 ; 时重新计算。哪个最好取决于您的实施细节。abget_c