7 AngularJS 的致命罪

下面列出了开发人员在使用 AngularJS 功能时经常犯的一些错误,一些经验教训和解决方案。

1.通过控制器操作 DOM

这是合法的,但必须避免。控制器是你定义依赖项,将数据绑定到视图以及进一步构建业务逻辑的位置。你可以从技术上操作控制器中的 DOM,但是只要你在应用程序的另一部分需要相同或类似的操作,就需要另一个控制器。所以这种方法的最佳实践是创建一个包含所有操作的指令,并在整个应用程序中使用该指令。因此,控制器保持视图完好无损并完成它的工作。在指令中,链接函数是操作 DOM 的最佳位置。它具有对范围和元素的完全访问权限,因此使用指令时,你还可以利用可重用性。

link: function($scope, element, attrs) {
    //The best place to manipulate DOM
}

你可以通过多种方式访问​​链接函数中的 DOM 元素,例如 element 参数,angular.element() 方法或纯 Javascript。

2.翻译中的数据绑定

AngularJS 以其双向数据绑定而闻名。但是,有时你可能会遇到你的数据仅在指令内单向绑定。停在那里,AngularJS 没有错,但可能是你。指令是一个有点危险的地方,因为涉及儿童范围和孤立的范围。假设你有一个包含一个转换的以下指令

<my-dir>
    <my-transclusion>
    </my-transclusion>
</my-dir>

在我的转换中,你有一些元素绑定到外部作用域中的数据。

<my-dir>
    <my-transclusion>
        <input ng-model="name">
    </my-transclusion>
</my-dir>

上面的代码无法正常工作。这里,transclusion 创建了一个子范围,你可以获得 name 变量,但是你对这个变量所做的任何改变都会保留在那里。因此,你可以真正将此变量作为 $ parent.name 访问。但是,这种用法可能不是最好的做法。更好的方法是将变量包装在对象中。例如,在控制器中,你可以创建:

$scope.data = {
    name: 'someName'
}

然后在转换中,你可以通过’data’对象访问此变量,并看到双向绑定完美​​运行!

<input ng-model="data.name">

不仅在转换中,而且在整个应用程序中,使用点分表示法是个好主意。

3.多个指令在一起

只要遵守规则,在同一元素中一起使用两个指令实际上是合法的:两个隔离的范围不能存在于同一个元素上。一般来说,在创建新的自定义指令时,你可以分配一个隔离的范围以便于参数传递。假设指令 myDirA 和 myDirB 具有 isoleted 范围而 myDirC 没有,则以下元素将是有效的:

<input my-dir-a my-dirc>

而以下元素将导致控制台错误:

<input my-dir-a my-dir-b>

因此,必须明智地使用指令,并考虑范围。

4.滥用$ emit

$ emit,$ broadcast 和$ on,这些工作在发送者 - 接收者原则中。换句话说,它们是控制器之间的通信手段。例如,以下行从控制器 A 发出’someEvent’,由相关控制器 B 捕获。

$scope.$emit('someEvent', args);

并且以下行捕获’someEvent'

$scope.$on('someEvent', function(){});

一切似乎都很完美但请记住,如果尚未调用控制器 B,则不会捕获事件,这意味着必须调用发射器和接收器控制器才能使其工作。再说一遍,如果你不确定你肯定要使用$ emit,那么构建服务似乎是一种更好的方法。

5.滥用$ scope。$ watch

$ scope。$ watch 用于观察变量变化。每当变量发生变化时,都会调用此方法。但是,一个常见的错误就是更改$ scope 内的变量。$ watch。这会在某些时候导致不一致和无限$ digest 循环。

$scope.$watch('myCtrl.myVariable', function(newVal) {
    this.myVariable++;
});

所以在上面的函数中,确保你对 myVariable 和 newVal 没有任何操作。

6.将方法绑定到视图

这是最致命的罪行之一。AngularJS 具有双向绑定功能,每当更改内容时,视图都会多次更新。因此,如果将方法绑定到视图的属性,则该方法可能会被调用一百次,这也会让你在调试期间发疯。但是,只有一些为方法绑定而构建的属性,例如 ng-click,ng-blur,ng-on-change 等,它们将方法视为 paremeter。例如,假设你的标记中包含以下视图:

<input ng-disabled="myCtrl.isDisabled()" ng-model="myCtrl.name">

在这里,你可以通过 isDisabled 方法检查视图的禁用状态。在控制器 myCtrl 中,你有:

vm.isDisabled = function(){
    if(someCondition)
        return true;
    else
        return false;
}

从理论上讲,这似乎是正确的,但从技术上讲,这会导致过载,因为该方法将运行无数次。为了解决这个问题,你应该绑定一个变量。在你的控制器中,必须存在以下变量:

vm.isDisabled

你可以在激活控制器时再次启动此变量

if(someCondition)
    vm.isDisabled = true
else
    vm.isDisabled = false

如果条件不稳定,你可以将其绑定到另一个事件。然后你应该将这个变量绑定到视图:

<input ng-disabled="myCtrl.isDisabled" ng-model="myCtrl.name">

现在,视图的所有属性都具有他们所期望的内容,并且方法仅在需要时运行。

7.不使用 Angular 的功能

AngularJS 通过一些功能提供了极大的便利,不仅简化了代码,而且提高了效率。其中一些功能如下:

  1. angular.forEach for the loops(注意,你不能破坏它,你只能防止进入身体,所以在这里考虑性能。)
  2. **** DOM 选择器的 angular.element
  3. angular.copy :当你不应该修改主对象时使用它
  4. 表格验证已经很棒了。使用脏,原始,触摸,有效,必需等。
  5. 除了 Chrome 调试器,还可以使用远程调试进行移动开发。
  6. 并确保你使用 Batarang 。这是一个免费的 Chrome 扩展程序,你可以轻松检查范围