为什么在控制器中操纵 DOM 被认为是个坏主意?

Why is it considered a bad idea to manipulate DOM in controllers?

很多人告诉我,在控制器中操纵DOM是一件非常糟糕的事情,但究竟是什么原因呢?它如何影响您正在制作的应用程序? 这样做的最佳做法是什么?它是如何完成的?

对于大多数具有 jQuery 背景的开发人员来说,AngularJS 需要进行重大的思维转变。

在使用 AngularJS 时不进行 jQuery 风格的 DOM 操作的主要原因是您的 Angular 应用程序将不知道您所做的任何更改到 DOM 和 jQuery,因此如果不进入主要的 Angular hackery,您将无法将这些 DOM 元素绑定到任何模型中。

至于最佳实践,我建议您学习 http://codeschool.com 中的全套教程,以帮助您从 "jQuery mindset" 飞跃到纯粹的 Angular 心态.

作为 angular 开发人员,我做过的最好的事情就是从我的 Angular 项目中完全删除了 jQuery 库,这样我就不想 return以我古老而错误的方式。

但是为了更具体地回答您的问题,有很多方法可以在 Angular 应用程序中向 DOM 添加元素。如果您想弄清楚如何做某事 "Angular Way".

,我建议您 post 一些代码和一个具体问题

完美的例子是 jQuery 的 append() 和 remove()。这些在 Angular 应用程序中没有位置,因为 jQuery 附加的任何元素对 Angular 的模型都不可见,使它们对应用程序本身无用。

因此,您可能想要使用 ng-repeat 指令渲染 DOM 元素,而不是使用 jQuery 进行附加和删除(如果有多个类似 DOM 需要附加的元素)并通过使用 ng-click 将数据添加到 ng-repeat 指令绑定到的对象来添加 DOM 元素,或者如果没有多个相似的元素要附加,也许您只需要使用 ng-show 或 ng-if 在单击后仅呈现 DOM 元素。

下面是这两种方法的示例:
http://plnkr.co/edit/4MSOoTrGGom2DpGj00x4?p=preview

<body ng-controller="MainCtrl">
    <p ng-repeat="name in names">{{name}}</p>
    <form ng-submit="addName(newName)">
      <input ng-model="newName" type="text"/>
      <button type="submit">Add Name</button>
    </form>
    <br>
    <br>
    <h1 ng-show="showHeader">Header Element</h1>
    <button ng-show="!showHeader" ng-click="showHeader = !showHeader">Show Header</button>
    <button ng-show="showHeader" ng-click="showHeader = !showHeader">Hide Header</button>
  </body>

JS:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.names = ['Ramm', 'John', 'Keith', 'Susan', 'Janice'];

  $scope.addName = function(newName){
    $scope.names.push(newName);
  };

});

您将操纵指令中的 DOM 个元素。你必须了解这些东西,

  • 指令:- 它们是使用和修改 DOM 的强大工具 .Angular 将指令定义为用于 DOM 操作的代码块

  • Controllers:- 控制器应该纯粹用于连接服务、依赖项和其他对象,并通过作用域将它们分配给视图。当需要在您的视图中处理复杂的业务逻辑时,它们也是一个很好的选择。

  • 服务:-服务主要是控制器之间通信的一种方式,但是你可以将一个服务注入到另一个服务中。服务通常用作访问数据存储的一种方式

请阅读这些,directiveVsserviceVsController and when to use what?

您应该将 DOM 操作放在指令中并尽可能使用 angular 数据绑定来进行 DOM 操作。

您可以将所有 DOM 操作放入控制器中,但这通常会导致单片控制器。由于存在更适合 DOM 通过数据绑定和指令进行操作的模式,因此您应该充分利用它们。

Technically controller should be smaller & compact, it should not be playing with a DOM. Controller will only interested to have a business logic & binding level logic that are being called on events.

根据我的观点,“你不应该从控制器操纵DOM”背后的原因是,这只是因为关注点分离。如果您从控制器执行 DOM 操作,那么它会与您的控制器紧密耦合,并且那段代码无法重用。因此,通过在指令中编写该代码,相同的代码可以很容易地成为可插入和可重用的组件。您可以在其他地方使用相同的 DOM 操作,只需将指令 tag/element.

查看了指令定义,然后你会分析它只是想玩 DOM,因为它在使用 preLInk 函数渲染它之前给了一个控制器 DOM & post 渲染 DOM 你可以在 postLink 函数中得到。

还有指令让你可以使用指令元素,你不需要让它编译,因为 element 已经用 jQLite 编译了,它是 jQuery 中使用的较小版本=24=]。这里不需要选择器来获取指令元素 DOM.

最简单的解释就是可测试性和可重用性。

Controllers should contain only business logic. Putting any presentation logic into Controllers significantly affects its testability. Angular has databinding for most cases and directives to encapsulate manual DOM manipulation. Understanding Controllers