lat*_*lip 32 javascript angularjs angularjs-rootscope
在角度,我有一个对象将通过服务暴露在我的应用程序中.
该对象上的某些字段是动态的,并且将通过使用该服务的控制器中的绑定正常更新.但是一些字段是计算属性,取决于其他字段,需要动态更新.
这里有一个简单的例子(这是工作在jsbin 这里).我的服务模型公开领域a,b并c在那里c通过以下公式计算a + B在calcC().请注意,在我的实际应用程序中,计算要复杂得多,但实质内容就在这里.
我能想到让它工作的唯一方法是将我的服务模型绑定到$rootScope,然后$rootScope.$watch用来监视任何控制器更改a或b何时更改,重新计算c.但这看起来很难看.有没有更好的方法呢?
第二个问题是表现.在我的整个应用程序a和b是对象的大名单,其中获得合计下来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)
虽然从较高的层面来看,我同意bmleite的回答($ rootScope存在使用,并且使用$ watch似乎适用于您的用例),我想提出一种替代方法.
使用$rootScope.$broadcast推变为$rootScope.$on听众,那么这将重新计算你的c价值.
这可以手动完成 - 即,当您主动更改a或b值时,或者甚至可能在短暂的超时时间来限制更新的频率.更进一步的是在您的服务上创建一个"脏"标志,这样c只在需要时计算.
显然,这种方法意味着更多地参与控制器,指令等的重新计算 - 但如果你不想将更新绑定到每个可能的更改a或者b,那么问题就变成了"在哪里划线".
一般来说,这可能不是一个好主意。(一般来说)将模型实现暴露给所有调用者也是不好的做法,如果没有其他原因,重构会变得更加困难和繁重。我们可以轻松解决这两个问题:
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