简体   繁体   English

AngularJS - 为什么在控制器中操作DOM是一件坏事?

[英]AngularJS - why manipulating DOM in controller is a bad thing?

Its common knowledge that DOM manipulations should not be performed in AngularJS Controller, its very hard however to find why exactly is it a bad thing. 众所周知,DOM操作不应该在AngularJS控制器中执行,但是很难找到为什么它确实是一件坏事。 All the sources say its difficult to test and because controller should be used for communication between directives, but fail to illustrate with code why this is a bad thing. 所有消息来源都说它难以测试,因为控制器应该用于指令之间的通信,但是没有用代码说明为什么这是一件坏事。

From my understanding I would think that controller, unlike directive, is not associated with any specific HTML, hence all the DOM modifications controller would do would very possibly fail. 根据我的理解,我认为控制器与指令不同,不与任何特定的HTML相关联,因此控制器所做的所有DOM修改都很可能会失败。 This would sure complicate development and testing. 这肯定会使开发和测试变得复杂。

Controller in directives being executed before link functions of child directives would also fail as the controller might not be aware of what the actual HTML of the child directives is. 在子指令的链接函数之前执行的指令中的控制器也将失败,因为控制器可能不知道子指令的实际HTML是什么。 Link is executed after controller function and might modify HTML structure. 链接在控制器功能之后执行,可能会修改HTML结构。

I hope I make sense here and if someone could clarify why manipulating DOM from controller is a bad thing, maybe some code exampleor link that explains it well that would be great. 我希望我在这里有意义,如果有人能澄清为什么从控制器操纵DOM是一件坏事,也许一些代码示例或链接可以很好地解释它。

The reason it is more difficult to prove their point with a code sample is that the reason can't really be represented by a short code snippet (short enough for Stack Overflow). 使用代码示例更难以证明自己的观点的原因是,原因无法真正用短代码片段表示(对于Stack Overflow来说足够短)。 It is really a maintainability precaution. 这实际上是一种可维护性预防措施。 Over the long term, you want to be able to independently alter the logic behind controllers and views independently, because otherwise a coupled controller and view pair tend to stay that way and limit each other in their ability to change their functionality without breaking the other. 从长远来看,您希望能够独立地独立地改变控制器和视图背后的逻辑,因为否则耦合的控制器和视图对倾向于保持这种方式,并且在不破坏另一个的情况下改变其功能的能力相互限制。 As soon as you decide to change anything about the view, you have the chance of making your controller code break without even touching it. 一旦您决定更改有关视图的任何内容,您就有可能在不触及控制器代码的情况下使控制器代码中断。

Testing becomes easier over time because the more tests you have, the more you wish that things were more modular and dependent on as little variables and parameters as possible. 随着时间的推移,测试变得越来越容易,因为您拥有的测试越多,您就越希望事物更加模块化,并且尽可能少地依赖于变量和参数。

Again, it is maintenance that drives this suggestion. 同样,正是维护推动了这一建议。 The problems listed above might not be that bad starting out. 上面列出的问题可能并不是那么糟糕的开始。 But imagine adopting a project that you didn't build from the ground up and know all the intricacies behind the coupling between controller and view that hold this application together. 但是想象一下,采用一个你没有从头开始构建的项目,并且知道控制器和视图之间耦合背后的所有复杂性,将这个应用程序结合在一起。 What if your application reaches so many thousands of lines of code that it would be impossible for you to know all these intricacies even if you DID build it from the ground up? 如果您的应用程序达到如此多的代码行,那么即使您从头开始构建它,您也无法知道所有这些错综复杂的内容怎么办?

For a more general understanding of why design patterns like the one you have alluded to are necessary, you can refer to this google search that will take you on a journey as long as you are willing to take. 为了更全面地了解为什么设计模式与您提到的设计模式是必要的,您可以参考这个谷歌搜索 ,只要您愿意,这将带您踏上旅程。 And for a general understanding of why design patterns even exist and why many people end up suggesting the same thing over and over again, you can refer to one of the catalysts to the introduction of design patterns, Christopher Alexander . 为了大致了解为什么设计模式甚至存在以及为什么许多人最终会一遍又一遍地提出同样的建议,你可以参考其中一个催化剂来引入设计模式, 克里斯托弗亚历山大 He shows us that patterns are what they are because they work well and people repeat what works well. 他向我们展示了模式就是它们的原因,因为它们运作良好,人们重复运作良好。

If you look at the ever so popular question "Thinking in AngularJS" if I have a jQuery background? 如果你看一个如此流行的问题“Thinking in AngularJS”,如果我有一个jQuery背景? you will get some hints. 你会得到一些提示。

One of the biggest factor that i think DOM manipulation is neither needs nor done is because Angular uses declarative approach when it comes to DOM linking as against the imperative approach that you would use with direct DOM manipulation. 我认为DOM操作既不需要也不需要完成的最大因素之一是因为当涉及DOM链接时,Angular使用声明性方法,而不是使用直接DOM操作的命令式方法。 Some of the answers detail this difference between declarative and imperative approach. 一些答案详细说明了声明式和命令式方法之间的这种区别。

With jQuery you tell the DOM what needs to happen, step by step. 使用jQuery,您可以一步一步地告诉DOM需要发生什么。 With AngularJS you describe what results you want but not how to do it. 使用AngularJS,您可以描述所需的结果,但不能描述如何执行此操作。 More on this here. 更多关于这里。 Also, check out Mark Rajcok's answer. 另外,请查看Mark Rajcok的答案。

A more comprehensive treatment of this topic is also available here What is the difference between declarative and imperative programming 此处还可以对此主题进行更全面的处理。 声明式编程和命令式编程之间的区别是什么

With such an approach the controller implementation is simplified, and we start to get real value as code base size grows and complexity increases. 通过这种方法,控制器实现得以简化,随着代码库大小的增加和复杂性的增加,我们开始获得真正的价值。

My perspective is bit different and covers more than testing. 我的观点略有不同,涵盖的不仅仅是测试。 It is the ability of the designer to have control over the HTML layout that otherwise would be taken over by writing code inside of the Angular Controller. 设计人员能够控制HTML布局,否则将通过在Angular Controller内编写代码来接管。 Consider the following snippet (it is just a simple example) 考虑以下片段(这只是一个简单的例子)

<div ng-repeat="article in articles">
    <p class="article-body">{{article.text}}</p>
</div>

This example just iterates over a collection and prints article in a separate paragraph tag. 此示例仅迭代集合并在单独的段落标记中打印文章。 While it is certainly possible to loop over the collection in an Angular Controller and dynamically generate paragraph tags with text inside it. 虽然可以在Angular Controller中循环遍历集合并动态生成包含文本的段落标记。 It will take away designer's capability to modify look & feel. 它将剥夺设计师修改外观和感觉的能力。 Hence, If there is a requirement to show the article title, instead of doing this 因此,如果需要显示文章标题,而不是这样做

<div ng-repeat="article in articles">
    <span class="article-title">{{article.title}}</span>
    <p class="article-body">{{article.text}}</p>
</div>

the designer will now have to locate Angular Controller code to modify DOM manipulation. 设计人员现在必须找到Angular Controller代码来修改DOM操作。 Just compare above two approaches and guess which one will provide more flexibility. 只需比较以上两种方法,并猜测哪一种方法将提供更大的灵活性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM