Angular: 如何编译一次然后销毁所有手表?
Angular: How do I compile once then destroy all watches?
由于性能问题,我希望能够简单地编译一次模板片段,然后从中完全删除所有手表等,只需将最终模板仅用于显示目的。
我尝试使用 $compile,但是一旦我在作用域上使用 $destroy,那么包括已解析内容在内的所有内容都会恢复为默认值。
注意:这是关于 Angularjs 1.5,而不是 Angular 2
-----编辑 1------
@Stepan Kasyanenko 建议我可以使用单向绑定。我实际上正在使用它,但遇到了一些问题:
我有数千个表单行需要显示,angularjs 无法处理这么多的手表,所以我决定通过只打印这些行的显示版本来作弊。每当用户单击一行进行编辑时,我就会将其换成一个真正的可编辑模型。
对于这些仅显示的行,我使用的是单向绑定。
如果我也能跳过单向绑定就太好了,因为它仍然会产生一些性能问题,尽管比 ngModel 少得多,这就是我问这个问题的原因。
使用单向绑定,似乎出于某种原因,即使在不同站点上使用相同的代码,行为也是不稳定的。有时,当用户键入内容时,实时模型会更新为 1 个长文本,但显示版本只会获得第一个文本(可能是因为单向绑定的工作方式。我能想到的唯一解决方案是重新编译此时显示行?
您可以使用 one-way binding.
例如jsfiddle:
angular.module('ExampleApp', [])
.controller('ExampleController', function($scope) {
$scope.oneWay = "one";
$scope.twoWay = "two";
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController">
<div> One way
<input ng-model="oneWay"> {{::oneWay}}
</div>
<div> Two way
<input ng-model="twoWay"> {{twoWay}}
</div>
</div>
</div>
更新
为了绘制大量数据,我做了一些对比
示例 jsfiddle
- AngularJs v1.4.8。具有单向绑定。 10 万条记录 - 脚本 7 秒,渲染 7 秒。
- jQuery v2.2.3。 10 万条记录 - 脚本 8 秒,渲染 6 秒。结果可能会更好。需要通过单独的考试。
- 原生 JS。 10 万条记录 - 脚本 0.3 秒,渲染 6 秒。
如您所见,最快的方式 - Native JS.
angular.module('ExampleApp', [])
.controller('ExampleController', function() {
var vm = this;
vm.countRow = 100000;
vm.arrayAngular = [];
vm.startGenerateAngular = function() {
vm.arrayAngular = [];
for (var i = 0; i < vm.countRow; i++) {
vm.arrayAngular.push(i);
}
}
});
function startGenerateJQuery() {
var count = $("#countRow").val() * 1;
var $content = $("#contentJQuery");
$content.html("");
for (var i = 0; i < count; i++) {
var divParent = $('<div>');
var divChild = $('<div>');
divChild.text(i);
divParent.append(divChild);
$content.append(divParent);
}
}
function startGenerateNative() {
var count = $("#countRow").val() * 1;
var content = document.querySelector("#contentNative");
content.innerHTML = "";
for (var i = 0; i < count; i++) {
var divParent = document.createElement('div');
var divChild = document.createElement('div');
divChild.innerText = i;
divParent.appendChild(divChild);
content.appendChild(divParent);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController as vm">
<input id="countRow" ng-model="vm.countRow">
<div>Generate angular: 100k records - 7 sec on script, 7 second on render
<br>
<input type="button" ng-click="vm.startGenerateAngular()" value="Go">
</div>
<div>Generate jQuery: 100k records - 8 sec on script, 6 second on render
<br>
<input type="button" onclick="startGenerateJQuery()" value="Go">
</div>
<div>Generate Native: 100k records - 0.3 sec on script, 6 second on render
<br>
<input type="button" onclick="startGenerateNative()" value="Go">
</div>
<div ng-repeat="item in vm.arrayAngular">
<div>{{::item}}</div>
</div>
<div id="contentJQuery">
</div>
<div id="contentNative">
</div>
</div>
</div>
由于性能问题,我希望能够简单地编译一次模板片段,然后从中完全删除所有手表等,只需将最终模板仅用于显示目的。
我尝试使用 $compile,但是一旦我在作用域上使用 $destroy,那么包括已解析内容在内的所有内容都会恢复为默认值。
注意:这是关于 Angularjs 1.5,而不是 Angular 2
-----编辑 1------
@Stepan Kasyanenko 建议我可以使用单向绑定。我实际上正在使用它,但遇到了一些问题:
我有数千个表单行需要显示,angularjs 无法处理这么多的手表,所以我决定通过只打印这些行的显示版本来作弊。每当用户单击一行进行编辑时,我就会将其换成一个真正的可编辑模型。 对于这些仅显示的行,我使用的是单向绑定。
如果我也能跳过单向绑定就太好了,因为它仍然会产生一些性能问题,尽管比 ngModel 少得多,这就是我问这个问题的原因。
使用单向绑定,似乎出于某种原因,即使在不同站点上使用相同的代码,行为也是不稳定的。有时,当用户键入内容时,实时模型会更新为 1 个长文本,但显示版本只会获得第一个文本(可能是因为单向绑定的工作方式。我能想到的唯一解决方案是重新编译此时显示行?
您可以使用 one-way binding.
例如jsfiddle:
angular.module('ExampleApp', [])
.controller('ExampleController', function($scope) {
$scope.oneWay = "one";
$scope.twoWay = "two";
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController">
<div> One way
<input ng-model="oneWay"> {{::oneWay}}
</div>
<div> Two way
<input ng-model="twoWay"> {{twoWay}}
</div>
</div>
</div>
更新
为了绘制大量数据,我做了一些对比
示例 jsfiddle
- AngularJs v1.4.8。具有单向绑定。 10 万条记录 - 脚本 7 秒,渲染 7 秒。
- jQuery v2.2.3。 10 万条记录 - 脚本 8 秒,渲染 6 秒。结果可能会更好。需要通过单独的考试。
- 原生 JS。 10 万条记录 - 脚本 0.3 秒,渲染 6 秒。
如您所见,最快的方式 - Native JS.
angular.module('ExampleApp', [])
.controller('ExampleController', function() {
var vm = this;
vm.countRow = 100000;
vm.arrayAngular = [];
vm.startGenerateAngular = function() {
vm.arrayAngular = [];
for (var i = 0; i < vm.countRow; i++) {
vm.arrayAngular.push(i);
}
}
});
function startGenerateJQuery() {
var count = $("#countRow").val() * 1;
var $content = $("#contentJQuery");
$content.html("");
for (var i = 0; i < count; i++) {
var divParent = $('<div>');
var divChild = $('<div>');
divChild.text(i);
divParent.append(divChild);
$content.append(divParent);
}
}
function startGenerateNative() {
var count = $("#countRow").val() * 1;
var content = document.querySelector("#contentNative");
content.innerHTML = "";
for (var i = 0; i < count; i++) {
var divParent = document.createElement('div');
var divChild = document.createElement('div');
divChild.innerText = i;
divParent.appendChild(divChild);
content.appendChild(divParent);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController as vm">
<input id="countRow" ng-model="vm.countRow">
<div>Generate angular: 100k records - 7 sec on script, 7 second on render
<br>
<input type="button" ng-click="vm.startGenerateAngular()" value="Go">
</div>
<div>Generate jQuery: 100k records - 8 sec on script, 6 second on render
<br>
<input type="button" onclick="startGenerateJQuery()" value="Go">
</div>
<div>Generate Native: 100k records - 0.3 sec on script, 6 second on render
<br>
<input type="button" onclick="startGenerateNative()" value="Go">
</div>
<div ng-repeat="item in vm.arrayAngular">
<div>{{::item}}</div>
</div>
<div id="contentJQuery">
</div>
<div id="contentNative">
</div>
</div>
</div>