它是使用角度的$手表控制器反模式? [英] Is it an antipattern to use angular's $watch in a controller?

查看:133
本文介绍了它是使用角度的$手表控制器反模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的永无止境的追求做事的正确的角度来,我一直在阅读了很多关于如何有控制器的观察角度服务举行模型的变化。

In my never ending quest to do things the "proper" angular way, I have been reading a lot about how to have controllers observe the changes in models held in angular services.

一些网站使用$手表说在控制器上是断然错误的:

Some sites say using a $watch on a controller is categorically wrong:

不要在控制器使用$手表。这是很难测试,并在几乎所有情况下完全不必要的。使用的范围方法来更新值(S)的手表,而不是改变。

DON'T use $watch in a controller. It's hard to test and completely unnecessary in almost every case. Use a method on the scope to update the value(s) the watch was changing instead.

其他只要你清理之后似乎与它的罚款自己:

Others seem fine with it as long as you clean up after yourself:

在$表函数本身返回调用时,将取消绑定$手表的功能。因此,当不再需要$手表,我们简单地调用由$表返回的功能。

The $watch function itself returns a function which will unbind the $watch when called. So, when the $watch is no longer needed, we simply call the function returned by $watch.

有<一个href=\"http://stackoverflow.com/questions/15911014/watching-a-values-in-a-service-from-a-controller\">SO问题和 ,似乎说的对了,其他知名网站的使用$腕表在控制器注意到在角服务维护的模式变化的好办法。

There are SO questions and other reputable sites that seem to say right out that using a $watch in a controller is a great way to notice changes in an angular-service-maintained model.

https://github.com/angular/angular.js/wiki/Best-Practices现场,我想我们可以给多一点的重量,直接说那$范围。$手表应该更换事件的需要。然而,对于复杂的SPA的被处理向上的100款和REST端点,选择使用$观看,以避免事件的 $广播/ $发出可能与最终的很多手表。在另一方面,如果我们不使用$手表,为不平凡的应用程序,我们最终万吨事件面条的。

The https://github.com/angular/angular.js/wiki/Best-Practices site, which I think we can give a bit more weight to, says outright that $scope.$watch should replace the need for events. However, for complex SPA's that are handling upwards of 100 models and REST endpoints, choosing to use $watch to avoid events with $broadcast/$emit could end up with lots of watches. On the other hand, if we don't use $watch, for non-trivial apps we end up tons of event spaghetti.

这是一赔/输的局面?它是事件和手表的一个错误的选择?我知道你可以使用2路对于许多情况约束力,但有时你只是需要的办法,听取更改。

Is this a lose/lose situation? Is it a false choice between events and watches? I know you can use the 2-way binding for many situations, but sometimes you just need a way to listen for changes.

修改

宜兰Frumer的评论让我重新思考我要问,所以也许而不只是询问是否是主观好/坏在控制器中使用$手表,让我提出的问题是这样的:

Ilan Frumer's comment made me rethink what I'm asking, so perhaps instead of just asking whether it is subjectively good/bad to use a $watch in a controller, let me put the questions this way:

哪个实现很可能先建立一个性能瓶颈?有控制器监听事件(其中有已播放/发射),或设立 $观看 -es的控制器。请记住,大型的应用程序。

Which implementation is likely to create a performance bottleneck first? Having controllers listen for events (which had to have been broadcast/emitted), or setting up $watch-es in controllers. Remember, large-scale app.

这实现首先创建一个维护头痛: $观看 -es或事件?可以说有一个耦合(紧/松)无论哪种方式......事件观察者需要知道如何倾听和 $观看 -es外部值(如 MyDataService.getAccountNumber())都需要知道的事情发生以外的$范围。

Which implementation creates a maintenance headache first: $watch-es or events? Arguably there is a coupling (tight/loose) either way... event watchers need to know what to listen for, and $watch-es on external values (like MyDataService.getAccountNumber()) both need to know about things happening outside their $scope.

**编辑过了一年之后**

** EDIT over a year later **

角改变/提高了很多,因为我问过这个问题,但我还是言归正传吧+ 1的,所以我想我会提到,在看的角度球队的code,我看到一个模式,当谈到在控制器观察家(或指令,那里是被摧毁了一个范围内):

Angular has changed / improved a lot since I asked this question, but I still get +1's on it, so I thought I would mention that in looking at the angular team's code, I see a pattern when it comes to watchers in controllers (or directives where there is a scope that gets destroyed):

$ $范围在('$毁灭',$ $范围手表('scopeVariable',functionIWantToCall)。)。

该做的事情采取$表函数返回的东西 - 一个可以被称为注销观察者功能 - 并把那个给事件处理程序当控制器被破坏了。这会自动清理看守。

$scope.$on('$destroy', $scope.$watch('scopeVariable', functionIWantToCall)); What this does it take what the $watch function returns - a function that can be called to deregister the watcher - and give that to the event handler for when the controller is destroyed. This automatically cleans up the watcher.

无论是在控制器手表code气味或不是,如果你使用他们,我相信角度球队使用这种模式应该成为一个强力推荐的如何的使用它们。

Whether watches in controllers are code smell or not, if you use them, I believe the angular team's use of this pattern should serve as a strong recommendation for how to use them.

谢谢!

推荐答案

我同时使用,因为说实话,我认为他们为不同的问题,不同的工具。

I use both, because honestly, I view them as different tools for different problems.

我给从我建立一个应用程序的示例。我有接收的动态数据模型从网络套接字服务器复杂的WebSocket服务。该服务本身不关心什么型号的样子,但是,当然,控制器肯定不会。

I'll give an example from an application that I built. I had a complex WebSocket Service that received dynamic data models from a web-socket server. The service itself doesn't care what the model looks like, but, of course, the controller sure does.

当控制器被启动,它建立了一个 $观看服务数据对象上,这样它知道当它是特定的数据对象已经到达(如等待 Service.data.foo 存在。一旦这种模式应运而生,它能够双向数据绑定绑定到它和包装箱它,手表成了过时的,它被摧毁。

When the controller is initiated, it set up a $watch on the service data object so that it knew when it's particular data object had arrived (like waiting for Service.data.foo to exist. As soon as that model came into existence, it was able to bind to it and crate a two-way data-bind to it, the watch became obsolete, and it was destroyed.

在另一侧,该服务负责广播某些事件为好,因为有时候客户会从服务器接收文本命令。例如,服务器可能会请求客户端发送被存储在'$ rootScope整个应用程序中的一些元数据。一个。对()是在 $ rootScope module.run设置() 步骤侦听来自服务器的那些命令,从其他服务收集所需信息,并调用WebSocket的服务回报的要求发送数据。另外,如果我做了这个用 $腕表(),我会需要建立某种形式的任意可变的为它看,如我需要增加我每次收到请求时metadataRequests 。 A 播放达到同样的事情,而不必住在永久的记忆,就像我们的变量将。

On the other side, the service was responsible for broadcasting certain events as well, because sometimes the client would receive literal commands from the server. For instance, the Server might request that the client send some metadata that was stored in the '$rootScope' throughout the application. an .on() was set up in the $rootScope during module.run() step to listen for those commands from the server, gather needed information from other services, and call the WebSocket service back to send the data as requested. Alternatively, if I had done this using a $watch(), I would have needed to set up some sort of arbitrary variable for it to watch, like metadataRequests which I would need to increment every time I receive a request. A broadcast achieves the same thing without having to live in permanent memory, like our variable would.

从本质上讲,我使用了 $腕表()当是我希望看到的变化(特别是如果我需要的,前后和了解一个特定值值),我用的事件是否存在已满足该控制器需要了解更多高水平的条件。

Essentially, I use a $watch() when there is a specific value that I want to see change (especially if I need to know the before-and-after values), and I use events if there are more high-level conditions that have been met that the controllers need to know about.

至于表演,我不能告诉你哪一个会先瓶颈,但我觉得它这样的想法会让你使用每项功能,他们是最强的优势。举例来说,如果你使用 $的()而不是 $腕表()来查找数据的变化,你将不能访问前和变更后的值,这可能会限制你正在试图做。

With regards to performance, I couldn't tell you which one is going to bottleneck first, but I feel like thinking of it this way will let you use the strengths of each feature where they are strongest. For instance, if you use $on() instead of $watch() to look for changes in data, you will not have access to the values before and after the change, which could limit what you are trying to do.

这篇关于它是使用角度的$手表控制器反模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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