【问题标题】:Angular.js - Performance implications of binding a model to be watched, using $watchCollectionAngular.js - 使用 $watchCollection 绑定要监视的模型的性能影响
【发布时间】:2015-04-27 23:47:15
【问题描述】:

我正在尝试更好地了解新的代码库,但没有找到大量关于所做选择的性能影响的信息(或者我可能没有完全理解我所阅读的内容) .以前的维护者无法提供洞察力。

每个控制器都设置为在使用此模式最初呈现之前发出其数据请求:

$routeProvider.when('/path', { resolve: { someMethod: function($q) { var deferred = $q.defer(); .... do some stuff ... return deferred.promise; } });

然后将其注入控制器 - 这部分是有意义的,据我了解,它的性能更高,因为您通过等待数据首先通过来保存摘要。加载状态默认显示并在我们消化时删除。

注入参数的值——在本例中为someMethod——然后分配给this.someModel

在整个控制器中,剩余的方法和属性都是用this.doStuff = function() { ... }this.property = 'some string'等设置的。

最后,通过像这样设置$watchCollection 来设置手表并为$scope 提供属性:

$scope.$watchCollection(angular.bind(this.someModel, function() {
    return this;
}), function(newTitle, oldTitle) {
    if (newTitle.title !== oldTitle.title)
    {
        self.updateThings(newTitle);
    }  
});

我知道它将手表的上下文绑定到this 的当前上下文,然后使用$watchCollection 观察其属性的变化,这将对其顶级属性执行浅层引用检查。

根据this article,我知道在模板中使用{{ property }} 的属性会导致它们被监视,但在这种情况下,直到它们绑定到$watchCollection 才会被监视。

当然,这比使用$watch 并将true 传递给可选的对象相等参数要便宜,但是从性能的角度来看,它比将东西直接放在$scope 上更好还是更差?为什么,具体来说?

我以前从未见过这样的做法,所以任何可以让我更好地理解的读物、见解或事情都将不胜感激。

【问题讨论】:

  • 对我来说看起来很难看,如果需要监视对象,它应该是范围的一部分,然后只是 $scope.$watchCollection("someModel", ...)。性能将是相同的。当你问is it better than putting onto $scope 你到底是什么意思?如果您的意思是我所说的,那么性能是平等的。

标签: javascript angularjs performance


【解决方案1】:

我能想到的唯一真实的事情是,作者想直接将所有内容保持在范围之外,只填充控制器实例的属性,这些属性将通过controllerAs 属性中指定的属性在范围上可用路由定义对象。

但是,当这样做时,如果你想在作用域上设置$watches 以通知某事物的更改,你不能,因为你实际上并不知道它的作用域的什么属性将发布。

可以controllerAs 值确定一个约定,例如vmctrl 或其他任何东西,但这并不理想,而且很脆弱,并不真正值得关注控制器代码本身。但是如果你做出了让步,你可以改用$scope.$watchCollection('vm.someModel', ...

最后一个可能的原因是$scope.$watch()$scope.$watchCollection() 总是最终将函数作为他们用来获取摘要期间正在观察的事物的值的事物。如果您传递一个字符串,它会在后台使用$parse 服务将其转换为函数。如果直接传递函数,则不需要转换,因此可以认为这是一个小的性能改进。

真正的原因可能是其中一个、全部或没有,但它们是采用这种方法的正当理由。我真的很佩服它的纯洁性和对“控制器作为”的严格遵守,这是 Angular 团队和社区目前鼓励的流行策略。

【讨论】:

  • 谢谢格雷格!这是很好的澄清。这是一个奇怪的范例,但我会接受它,因为它可能是推荐的。
  • 有道理。但是一个字符串只被 $parsed 一次,所以不会有任何区别。我仍然不太清楚的是为什么使用angular.bind 而不是简单的匿名function() { return someModel; }(是的,您可以通过创建另一个闭包来保存闭包)
  • 是的,我无法回答您关于为什么angular.bind() 而不是直接返回someModel 的有效问题,抱歉。这似乎有点奇怪,而且这种方法中最没有意义的部分。但是考虑到其余代码是多么“纯粹”,作者可能是合理地打开了,所以也许毕竟有一个很好的理由。不过,他们应该说明原因。
猜你喜欢
  • 2015-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多