在控制器中使用 Angular 的 $watch 是反模式吗?

2024-04-23

在我永无休止地追求以“正确的”角度方式做事的过程中,我阅读了很多有关如何让控制器观察角度服务中保存的模型变化的文章。

一些网站 http://www.benlesh.com/2013/08/angularjs-watch-digest-and-apply-oh-my.html说在控制器上使用 $watch 是绝对错误的:

不要在控制器中使用 $watch。几乎在所有情况下都很难测试并且完全没有必要。使用范围上的方法来更新手表正在更改的值。

Others http://angular-tips.com/blog/2013/08/removing-the-unneeded-watches/只要你自己清理干净就可以了:

$watch 函数本身返回一个函数,该函数在调用时将解除 $watch 的绑定。因此,当不再需要 $watch 时,我们只需调用 $watch 返回的函数即可。

所以问题 https://stackoverflow.com/questions/15911014/watching-a-values-in-a-service-from-a-controller and 其他信誉良好的网站 https://github.com/angular/angular.js/wiki/Best-Practices这似乎表明,在控制器中使用 $watch 是注意到角度服务维护模型中变化的好方法。

The https://github.com/angular/angular.js/wiki/Best-Practices https://github.com/angular/angular.js/wiki/Best-Practices我认为我们可以给予更多重视的网站,直接表示 $scope.$watch 应该取代对事件的需求。然而,对于处理超过 100 个模型和 REST 端点的复杂 SPA,选择使用 $watch 来避免事件$broadcast/$emit最终可能是lots手表。另一方面,如果我们不使用 $watch,对于不平凡的应用程序,我们最终会得到大量的事件意大利面条。

这是双输的情况吗?赛事与腕表的选择是否错误?我知道您可以在很多情况下使用 2 向绑定,但有时您只是need一种倾听变化的方式。

EDIT

Ilan Frumer 的评论让我重新思考我的问题,所以也许不只是问在控制器中使用 $watch 主观上是好还是坏,让我这样提出问题:

哪种实现可能首先造成性能瓶颈?让控制器监听事件(必须已广播/发出),或设置$watch-es 在控制器中。请记住,大型应用程序。

哪种实现首先会造成维护难题:$watch-es 或事件?可以说,无论哪种方式都存在耦合(紧/松)......事件观察者需要知道要监听什么,并且$watch-es 外部值(例如MyDataService.getAccountNumber())两者都需要了解在其 $ 范围之外发生的事情。

**一年多后编辑**

自从我问这个问题以来,Angular 已经改变/改进了很多,但我仍然得到+1,所以我想我会提到,在查看 Angular 团队的代码时,我看到了控制器中观察者的模式(或存在被破坏范围的指令):

$scope.$on('$destroy', $scope.$watch('scopeVariable', functionIWantToCall)); $watch 函数返回的是什么 - 可以调用该函数来取消注册观察程序 - 并在控制器被销毁时将其提供给事件处理程序。这会自动清理观察者。

无论控制器中的手表是否有代码味道,如果你使用它们,我相信 Angular 团队对这种模式的使用应该作为强烈推荐how使用它们。

Thanks!


我使用两者,因为老实说,我将它们视为解决不同问题的不同工具。

我将给出一个我构建的应用程序的示例。我有一个复杂的 WebSocket 服务,它从 Web 套接字服务器接收动态数据模型。服务本身并不关心模型的外观,但是控制器当然关心。

当控制器启动时,它会设置一个$watch在服务数据对象上,以便它知道特定数据对象何时到达(例如等待Service.data.foo存在。一旦该模型出现,它就能够与其绑定并创建双向数据绑定,手表就变得过时了,并且被销毁了。

另一方面,服务还负责广播某些事件,因为有时客户端会从服务器接收文字命令。例如,服务器可能请求客户端发送一些存储在整个应用程序的“$rootScope”中的元数据。一个.on()成立于$rootScope期间module.run()步骤监听来自服务器的命令,从其他服务收集所需的信息,并回调 WebSocket 服务以根据请求发送数据。或者,如果我使用$watch(),我需要设置某种任意变量以供其观看,例如metadataRequests每次收到请求时我都需要增加它。 Abroadcast实现同样的事情,而不必像我们的变量那样存在于永久内存中。

本质上,我使用$watch()当我想要看到某个特定值的变化时(特别是如果我需要知道之前和之后的值),并且如果控制器需要知道更多高级条件已满足,我会使用事件关于。

关于性能,我无法告诉你哪一个首先会遇到瓶颈,但我觉得这样思考会让你利用每个功能最强大的优势。例如,如果您使用$on()代替$watch()要查找数据更改,您将无法访问更改之前和之后的值,这可能会限制您尝试执行的操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在控制器中使用 Angular 的 $watch 是反模式吗? 的相关文章

随机推荐