是绑定在一个糟糕的服务对象为角度的$ rootScope? [英] Is binding objects to angular's $rootScope in a service bad?

查看:121
本文介绍了是绑定在一个糟糕的服务对象为角度的$ rootScope?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

一些对象的字段是动态的,会被绑定在使用该服务的控制器被更新为正常。但一些字段是计算特性,依赖于其他领域,并需要被动态更新的。

下面是一个简单的例子(这是工作jsbin这里: http://jsbin.com/erudis/21/edit)。我的服务模型公开领域 A B C 其中, C 计算A + B calcC() 。请注意,我在实际应用中的计算是一个复杂得多,但本质就在这里。

我认为得到这个工作的唯一办法,就是我的服务模式绑定到$ rootScope,然后使用$ rootScope。$腕表观看任何控制器改变 A b 当他们这样做,重新计算 C 。但是这似乎难看。 是否有这样做?

更好的办法

第二个问题是性能。在我的整个应用程序 A B 是对象的大名单,其中获得聚集到 ç。这意味着$ rootScope。$腕表功能将被做了很多深刻的阵列检查,这听起来像它会影响性能的。

我有这一切都在一个骨干方法事件触发,它尽可能地减少了重新计算工作,但是角度似乎并没有与事件触发的方式发挥出色。 上的任何想法将是巨大的。


下面的示例应用程序。

  VAR Mymodule中= angular.module('Mymodule中',[]);//服务提供的模式提供给多个控制器
myModule.factory('AMODEL',函数($ rootScope){
  VAR基于myModel = {
    答:10,
    B:10,
    C:空
  };  从a和b //计算Ç
  calcC =功能(){
    myModel.c = parseInt函数(myModel.a,10)* parseInt函数(myModel.b,10);
  };  $ rootScope.myModel =基于myModel;
  $ rootScope手表$('myModel.a',calcC)。
  $ rootScope手表$('myModel.b',calcC)。  返回基于myModel;
});
myModule.controller('oneCtrl',函数($范围,AMODEL){
  $ scope.aModel = AMODEL;
});myModule.controller('twoCtrl',函数($范围,AMODEL){
  $ scope.anotherModel = AMODEL;
});


解决方案

虽然从一个高的水平,我与bmleite答案同意($ rootScope的存在是为了使用,而使用$表似乎为您的使用情况下工作) ,我想提出一个替代方案。

使用 $ rootScope。$广播推更改为 $ rootScope。$关于监听器,那么这将重新计算你的 C 值。

这既可以手动完成 - 即当你将积极变化 A B 值,或可能即使在很短的超时节流的更新的频率。一个步骤就可以进一步将是您的服务创建一个脏标志,让 C 需要时才计算。

显然,这种做法意味着在控制器,指令等重新计算了更多的参与 - 但如果你不想更新绑定到 A 或 b ,这个问题变成了'在哪里画线的问题。

In angular, I have an object that will be exposed across my application via a service.

Some of the fields on that object are dynamic, and will be updated as normal by bindings in the controllers that use the service. But some of the fields are computed properties, that depend on the other fields, and need to be dynamically updated.

Here's a simple example (which is working on jsbin here: http://jsbin.com/erudis/21/edit). My service model exposes fields a, b and c where c is calculated from a + B in calcC(). Note, in my real application the calculations are a lot more complex, but the essence is here.

The only way I can think to get this to work, is to bind my service model to the $rootScope, and then use $rootScope.$watch to watch for any of the controllers changing a or b and when they do, recalculating c. But that seems ugly. Is there a better way of doing this?


A second concern is performance. In my full application a and b are big lists of objects, which get aggregated down to c. This means that the $rootScope.$watch functions will be doing a lot of deep array checking, which sounds like it will hurt performance.

I have this all working with an evented approach in BackBone, which cuts down the recalculation as much as possible, but angular doesn't seem to play well with an evented approach. Any thoughts on that would be great too.


Here's the example application.

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;
});

解决方案

Although from a high level, I agree with the answer by bmleite ($rootScope exists to be used, and using $watch appears to work for your use case), I want to propose an alternative approach.

Use $rootScope.$broadcast to push changes to a $rootScope.$on listener, which would then recalculate your c value.

This could either be done manually - i.e. when you would be actively changing a or b values, or possibly even on a short timeout to throttle the frequency of the updates. A step further from that would be to create a 'dirty' flag on your service, so that c is only calculated when required.

Obviously such an approach means a lot more involvement in recalculation in your controllers, directives etc - but if you don't want to bind an update to every possible change of a or b, the issue becomes a matter of 'where to draw the line'.

这篇关于是绑定在一个糟糕的服务对象为角度的$ rootScope?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆