Zso*_*olt 9 html javascript dom angularjs reactjs
我是Angular的新手,但我已经听过(和读过)有关其渲染模型的一些"谣言",以及它与React的不同之处.
我已经阅读了Angular专家的一些帖子,他们声称如果你必须使用Angular渲染长列表,它可能会很慢,因为如果某些内容发生变化,Angular将重新呈现整个列表,而React(例如)"将不会重新呈现 - 一旦它已经被渲染,从头开始渲染整个列表,但它将在内部跟踪渲染的DOM元素,并在新调用时创建新的虚拟DOM,将其与前一个进行比较并仅应用更改"
(引自随机博客文章关于角度渲染问题)
所以当我开始学习Angular时,我的第一件事就是尝试这一点.
似乎我无法重现这个问题......
这是一个虚拟的Plunker,我创建它来重现这个问题.
您可以将新项添加到使用ng-repeat呈现的消息列表中,如下所示:
<table>
<tr ng-repeat="m in messages" class="{{name}}">
<td>{{m.message}}</td>
<td>{{m.date}}</td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
您可以单击可以更新一个此类项目的按钮,并且可以更新与列表完全无关的另一个属性(name)
现在,如果我打开开发人员工具栏,并在表格中修改项目的HTML属性,然后点击"添加新消息",我的修改不会被Angular丢失或覆盖 - 似乎Angular不会重新渲染DOM完全.它看起来很聪明.
Angular最近是否开始使用DOM差异?(我的演示使用Angular 1.4.0 beta)
仅仅因为从DOM渲染的角度来看,我只是没有看到React和Angular之间的巨大差异.
你能告诉我一个用例,它展示了Angular渲染模型的缺点吗?
关于这个话题有很多混乱,主要是因为它不是一个简单的"角度重新呈现一切"类型的答案.
角度数据绑定的基础(在1.x版本中)围绕着$digest循环和概念的概念$scope. $scope是一个"自我跟踪"它的属性的特殊对象,并使用该方法为每个属性创建一个JavaScript事件侦听器$scope.$watch().这些侦听器监视HTML中可更改输入元素和$scope属性的更改.
每当任何JavaScript侦听器触发时,$digest循环都会遍历每个项目,$watch并相应地更新值.您也可以调用$scope.$apply()手动执行$digest循环.此循环可以多次执行,因为对一个值的更改可能会影响$watch触发另一个值的另一个值$digest.但是,$digest循环确实有一个迭代上限,以确保它在循环引用上停止.
当您处理对象数组和特殊指令时,会出现问题ng-repeat.默认情况下,该$watch()函数仅检查对象引用相等性.在每个中$digest,AngularJS将检查新旧值是否是相同的"物理"对象,并且只有在您实际更改基础对象引用时才会调用其处理程序.
为了解决这个问题,ng-repeat创造它自己独特的scope.这允许$watch阵列中的每个元素都是唯一的.这里的挑战是,如果阵列本身发生变化,那么scope将重新生成此唯一$watch元素以及所有元素.推送,弹出,拼接数组可以创建许多$watch值.
Angular提供了一些方法来处理这个问题.
1.3中添加的新Bind Once语法允许只在表达式计算之前存在的侦听器. ng-repeat="element in ::elements"将遍历数组,填充DOM,然后销毁事件监听器.这对于DOM元素在评估后不会更改的情况非常理想.
使用可以积极地跟踪元素track by. ng-repeat="element in elements track by $id"将创建一个$watch唯一$id值,而不是元素在数组中的位置.这允许更稳定的$watch传播,并且在元素的值可能改变的情况下是理想的.
至于为什么在控制台中所做的更改没有丢失:首先,开发人员控制台中的更改不会触发任何事件监听器.其次,只有在$watch检测到更改时才会修改您更改的特定DOM元素.然而,这并不是HTML的"差异"; Angular不是"观看HTML",而是"观看数据",可以这么说.
| 归档时间: |
|
| 查看次数: |
2620 次 |
| 最近记录: |