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 通过一些功能提供了极大的便利,不仅简化了代码,而且提高了效率。其中一些功能如下:
- angular.forEach for the loops(注意,你不能破坏它,你只能防止进入身体,所以在这里考虑性能。)
- **** DOM 选择器的 angular.element
- angular.copy :当你不应该修改主对象时使用它
- 表格验证已经很棒了。使用脏,原始,触摸,有效,必需等。
- 除了 Chrome 调试器,还可以使用远程调试进行移动开发。
- 并确保你使用 Batarang 。这是一个免费的 Chrome 扩展程序,你可以轻松检查范围