再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结 (4)

然而入上文所说,肉眼不可见不代表不会跑脏检查。如果将 ng-show 替换为 ng-if 或 ng-switch-when

<div ng-if="selectedTab === 1">[[Tab 1 body...]]</div> <div ng-if="selectedTab === 2">[[Tab 2 body...]]</div> <div ng-if="selectedTab === 3">[[Tab 3 body...]]</div> <div ng-if="selectedTab === 4">[[Tab 4 body...]]</div>

有如下优点:

首先 DOM 树中的元素个数显著减少至四分之一,降低内存占用

其次 $watch 表达式也减少至四分之一,提升脏检查循环的速度

如果这个 tab 下面有 controller(例如每个 tab 都被封装为一个组件),那么仅当这个 tab 被选中时该 controller 才会执行,可以减少各页面的互相干扰

如果 controller 中调用接口获取数据,那么仅当对应 tab 被选中时才会加载,避免网络拥挤

当然也有缺点:

DOM 重建本身费时间

如果 tab 下有 controller,那么每次该 tab 被选中时 controller 都会被执行

如果在 controller 里面调接口获取数据,那么每次该 tab 被选中时都会重新加载

各位读者自己取舍。

3、给 ng-repeat 手工添加 track by

不恰当的 ng-repeat 会造成 DOM 树反复重新构造,拖慢浏览器响应速度,造成页面闪烁。除了上面这种比较极端的情况,如果一个列表频繁拉取 Server 端数据自刷新的话也一定要手工添加 track by,因为接口给前端的数据是不可能包含 $$hashKey 这种东西的,于是结果就造成列表频繁的重建。

其实不必考虑那么多,总之加上没坏处,至少可以避免 angular 生成 $$hashKey 这种奇奇怪怪的东西。

具体参看: 

 

脏检测的利弊?

很多人对Angular的脏检测机制感到不屑,推崇基于setter,getter的观测机制,在我看来,这只是同一个事情的不同实现方式,并没有谁完全胜过谁,两者是各有优劣的。

 

大家都知道,在循环中批量添加DOM元素的时候,会推荐使用DocumentFragment,为什么呢,因为如果每次都对DOM产生变更,它都要修改DOM树的结构,性能影响大,如果我们能先在文档碎片中把DOM结构创建好,然后整体添加到主文档中,这个DOM树的变更就会一次完成,性能会提高很多。

同理,在Angular框架里,考虑到这样的场景:

function TestCtrl($scope) {     $scope.numOfCheckedItems = 0;     var list = [];     for (var i=0; i<10000; i++) {         list.push({             index: i,             checked: false         });     }     $scope.list = list;     $scope.toggleChecked = function(flag) {         for (var i=0; i<list.length; i++) {             list[i].checked = flag;             $scope.numOfCheckedItems++;         }     }; }

如果界面上某个文本绑定这个numOfCheckedItems,会怎样?在脏检测的机制下,这个过程毫无压力,一次做完所有数据变更,然后整体应用到界面上。这时候,基于setter的机制就惨了,除非它也是像Angular这样把批量操作延时到一次更新,否则性能会更低。

 

所以说,两种不同的监控方式,各有其优缺点,最好的办法是了解各自使用方式的差异,考虑出它们性能的差异所在,在不同的业务场景中,避开最容易造成性能瓶颈的用法。

ng-if跟ng-show/hide的区别有哪些?

第一点区别是,ng-if 在后面表达式为 true 的时候才创建这个 dom 节点,ng-show 是初始时就创建了,用 display:block 和 display:none 来控制显示和不显示。第二点区别是,ng-if 会(隐式地)产生新作用域,ng-switch 、 ng-include 等会动态创建一块界面的也是如此。

ng-repeat迭代数组的时候,如果数组中有相同值,会有什么问题,如何解决?

会提示 Duplicates in a repeater are not allowed. 加 track by $index 可解决。当然,也可以 trace by 任何一个普通的值,只要能唯一性标识数组中的每一项即可(建立 dom 和数据之间的关联)。

ng-click中写的表达式,能使用JS原生对象上的方法,比如Math.max之类的吗?为什么?

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywzxj.html