Due to performance issue, I would like to be able to simply compile a template piece once, then completely remove all watches etc from it, simply use the final template for display purpose only.
I tried with $compile but as soon as I use $destroy on scope then everything including the parsed content is reversed back to default.
Note: this is regarding Angularjs 1.5, not Angular 2
-----Edit 1------
@Stepan Kasyanenko suggested I can use one-way binding. I'm actually using it but with some issues:
I have thousands of form rows I need to display and angularjs cannot handle this amount of watches, so I decided to cheat by printing a display version of these rows only. Whenever the user clicks on a row to edit then I swap it out with a real editable model. For these display only rows I'm using one-way binding.
It would be great if I can skip the one-way binding as well since it still creates some performance issue though much less than ngModel, that's why I asked the question.
With one-way binding, it seems like for some reason, even with the same code on the different sites behavior is flaky. Sometimes the live model is updated with 1 long text when the user types something, but the display version only get the 1st text (probably because of the way one-way binding should works. The only solution I can think of is to re-compile the display row at this time?
You can use one-way binding.
For example 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>
I did some comparisons for drawing large amounts of data.
Example on jsfiddle
As you can see the fastest way - the 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>