GVKun编程网logo

angularjs – $interpolate vs ng-repeat和一次性绑定的性能(angularjs数据绑定)

18

对于angularjs–$interpolatevsng-repeat和一次性绑定的性能感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解angularjs数据绑定,并且为您提供关于Angul

对于angularjs – $interpolate vs ng-repeat和一次性绑定的性能感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解angularjs数据绑定,并且为您提供关于Angular 学习系列 - - $interpolate 和 $parse、AngularJs ng-repeat 必须注意的性能问题、AngularJs ng-repeat必须注意的性能问题、AngularJs ng-repeat性能问题的宝贵知识。

本文目录一览:

angularjs – $interpolate vs ng-repeat和一次性绑定的性能(angularjs数据绑定)

angularjs – $interpolate vs ng-repeat和一次性绑定的性能(angularjs数据绑定)

在 http://www.binpress.com/tutorial/speeding-up-angular-js-with-simple-optimizations/135

据说,对于指令,使用插值比使用ng-repeat更好:

The ng-repeat directive is most likely the worst offender for
performance concerns,which means it can easily be abused. An
ng-repeat likely deals with Arrays of $scope Objects and this hammers
the $digest cycle’s performance.

For example,instead of rendering a global navigation using ng-repeat,
we Could create our own navigation using the $interpolate provider to
render our template against an Object and convert it into DOM nodes.

当使用角度1.3时,我们可以使用ng-repeat和一次时间绑定来实现相同的结果.

为此目的使用$interpolate更好吗?

解决方法

如果您打开< 1.3,我建议使用 bindonce,只需在ng-repeat旁边添加bindonce,并在重复部分中将ng- *指令更改为bo- *.它基本上与1.3的一次性绑定完全相同.

如果您的意思是你的意思是你应该使用$interpolate而不是1.3中的一次时间绑定,我会说使用ng-repeat进行一次时间绑定,因为没有任何观察者会减慢你的速度并且它更具可读性.尽管ng-repeat仍然会创建子范围,但如果您在这些范围内没有执行任何操作,则性能差异可以忽略不计.

根据经验,如果你没有检查观察者,即使有很多子范围,你也会在浏览器中遇到性能问题,因为在$digest之前渲染这么多元素会成为一个问题.

Angular 学习系列 - - $interpolate 和 $parse

Angular 学习系列 - - $interpolate 和 $parse

从数据到大模型应用,11 月 25 日,杭州源创会,共享开发小技巧

$interpolate

将一个字符串编译成一个插值函数。HTML 编译服务使用这个服务完成数据绑定。

使用:$interpolate(text,[mustHaveExpression],[trustedContext],[allOrNothing]);

text:需要被编译的字符串。

mustHaveExpression:boolean,如果为 true,那么 text 必须含有嵌入其中的表达式,不然将会返回 null,而不是预期的 interpolate function,默认为 false。

trustedContext:string,如果这个参数被提供,那么在返回相应的函数之前会使用 $sce.getTrusted (interpolatedResult, trustedContext) 对返回的结果做处理。

$interpolate 带有一个可选的第四个参数,allOrNothing。如果 allOrNothing 为 true,插值函数将会返回未定义除非所有嵌入表达式的计算结果不为 undefined。

使用代码:

<div ng-app="Demo" ng-controller="testCtrl as ctrl">  <input ng-model="ctrl.text" />{{ctrl.value}}  </div>

(function(){
     angular.module(''Demo'', [])
     .controller(''testCtrl'',["$interpolate","$scope",testCtrl]);     function testCtrl($interpolate,$scope) {var vm = this;var obj = { value: "Hello" };
        vm.text = "World";
        $scope.$watch("ctrl.text",function(n,o){           var interpolate = $interpolate("{{value}} " + n);
           vm.value = interpolate(obj);
        })
     }
  }());

$parse

将 Angular 表达式转换为函数。

使用:$parse(expression);

expression:被编译的表达式。

返回:表示表达式编译后的函数。function (context,locals)

context:对象,含有需要解析的语句中的表达式(通常是一个 scope 对象)。

locals:对象,局部变量的上下文对象,用于重写上下文中的值。

属性

literal:boolean,表达式的顶节点是否是一个 javascript 字面量。

constant:boolean, 表达式是否全部是由 javascript 的常量字面量组成。

assign:function (context,locals),可以用来在给定的上下文中修改表达式的值。

使用代码:

<div ng-app="Demo" ng-controller="testCtrl as ctrl">  {{ctrl.ParsedValue}}  </div>

(function(){
     angular.module(''Demo'', [])
     .controller(''testCtrl'',["$parse",testCtrl]);     function testCtrl($parse{         var context = {
             addfunction (a, breturn a + b; },
            mulfunction (a, breturn a * b }
         };         var data = {a2b3c4};         this.value = context.mul(data.a,context.add(data.b,data.c));// 平常的函数嵌套调用   2*(3+4) = 14 var expression = "mul(a, add(b, c))";// 表达式,将被转换为函数 this.ParsedValue = $parse(expression)(context, data); //执行上一句的函数   2*(3+4) = 14     }
  }());

AngularJs ng-repeat 必须注意的性能问题

AngularJs ng-repeat 必须注意的性能问题

转自http://www.cnblogs.com/MigCoder/p/3930264.html?utm_source=tuicool&utm_medium=referral

AngularJs 的 ng-repeat 让我们非常方便的遍历数组生成 Dom 元素,但是使用不当也会有性能问题。

在项目中我们使用 ng-repeat 加载完一个列表后,如果再次请求数据,然后过滤列表,代码可能会这么写:

<div ng-controller="Test"> <button ng-click="request()">请求新数据</button> <div ng-repeat="user in users"> {{user.name}} </div> </div>

Controller 的代码:

app.controller('Test',function($scope) {
    var users = [];
    for (var i = 0; i < 100; i++) {
        users[i] = {
            id: i,name: "User: " + i
        };
    }
    $scope.users = users;

    $scope.request = function () {
        // 从服务器加载新数据
        var result = [];

        // 直接重新赋值给 users
        $scope.users = result;
    };
});

查看 ng-repeat 的源码可以发现,当 ng-repeat 的数组被替换时,它默认并不会重新利用已有的 Dom 元素,而是直接将其全部删除并重新生成新的数组 Dom 元素:

// 将上次生成的所有 dom 移除
for (key in lastBlockMap) {
    if (lastBlockMap.hasOwnProperty(key)) {
        block = lastBlockMap[key];
        elementsToRemove = getBlockElements(block.clone);
        $animate.leave(elementsToRemove);
        forEach(elementsToRemove,255)">function(element) { element[NG_REMOVED] = true; });
        block.scope.$destroy();
    }
}

Dom 的频繁操作是非常不友好的,为什么 ng-repeat 不能利用已有的 dom 元素去更新数据呢?因为你没有把数组元素的标识属性告诉它,那么两次替换的时候它就没办法追踪了,我们可以看到 ng-repeat 往数组里每个元素加了一个 $$hashKey 的属性:

这个 key 是由 Angular 内部的 nextUid() 方法生成,类似数据库自增,但是是使用字符串。

现在我们明白了,因为每次替换数组都会导致 ng-repeat 为每个元素生成一个新 key,所以根本没办法重用已有的 Dom 元素,那么我们可以使用下边的语法来避免这个问题:

</button> // 使用 track by 标识 "user in users track by user.id">  这样 ng-repeat 就用将其缓存起来啦,当然可能你的数组元素没有一个标识属性,如果元素数量不多那么可以接受,不然还是建议你手动为其生成一个标识属性。

AngularJs ng-repeat必须注意的性能问题

AngularJs ng-repeat必须注意的性能问题

AngularJs 的 ng-repeat 让我们非常方便的遍历数组生成 Dom 元素,但是使用不当也会有性能问题。

在项目中我们使用 ng-repeat 加载完一个列表后,如果再次请求数据,然后过滤列表,代码可能会这么写:

<html>
<head>
	<title>AngularJs ng-repeat实例</title>
</head>
<body>
	<h1>AngularJs ng-repeat实例</h1>
	<div ng-controller="Test">
    <button ng-click="request()">请求新数据</button>
    <div ng-repeat="user in users">
        {{user.name}}
    </div>
	</div>
	<script src="jquery-1.8.3.js"></script>
	<script src="angular1.2.9.js"></script>
	<script src="app.js"></script>
</body>
</html>

Controller 的代码:

var app = angular.module('myModule',[]);
app.controller('Test',['$scope',function($scope) {

  var users = [];
	for (var i = 0; i < 10; i++) {
		users[i] = {
			id: i,name: "User: " + i
		};
	}
	$scope.users = users;

	$scope.request = function () {
		
		var newUsers = [];
		for (var i = 0; i < 10; i++) {
			newUsers[i] = {
				id: i,name: "NewUser: " + i
			};
		}
		
		// 从服务器加载新数据
		var result = newUsers;

		// 直接重新赋值给 users
		$scope.users = result;
	};
}]);

angular.element(document).ready(function() {   
 angular.bootstrap(document,['myModule']);  
});

查看 ng-repeat 的源码可以发现,当 ng-repeat 的数组被替换时,它默认并不会重新利用已有的 Dom 元素,而是直接将其全部删除并重新生成新的数组 Dom 元素:

// 将上次生成的所有 dom 移除
for (key in lastBlockMap) {
  if (lastBlockMap.hasOwnProperty(key)) {
    block = lastBlockMap[key];
    elementsToRemove = getBlockElements(block.clone);
    $animate.leave(elementsToRemove);
    forEach(elementsToRemove,function(element) { element[NG_REMOVED] = true; });
    block.scope.$destroy();
  }
}

Dom 的频繁操作是非常不友好的,为什么 ng-repeat 不能利用已有的 dom 元素去更新数据呢?因为你没有把数组元素的标识属性告诉它,那么两次替换的时候它就没办法追踪了,稍微修改如上实例,我们Debug可以看到 ng-repeat 往数组里每个元素加了一个$$hashKey的属性:

var app = angular.module('myModule',name: "NewUser: " + i
			};
		}
		
		// 从服务器加载新数据
		var result = newUsers;

	
		$scope.oldJsonStr = JSON.stringify($scope.users);
		$scope.oldToJson = angular.toJson($scope.users);
		
		// 直接重新赋值给 users
		$scope.users = result;
	};
}]);

angular.element(document).ready(function() {   
 angular.bootstrap(document,['myModule']);  
});

Debug跟踪如下:


这个 key 是由 Angular 内部的 nextUid() 方法生成,类似数据库自增,但是是使用字符串。

现在我们明白了,因为每次替换数组都会导致 ng-repeat 为每个元素生成一个新 key,所以根本没办法重用已有的 Dom 元素,那么我们可以使用下面track by语法来避免这个问题:

<html>
<head>
	<title>AngularJs ng-repeat实例</title>
</head>
<body>
	<h1>AngularJs ng-repeat实例</h1>
	<div ng-controller="Test">
    <button ng-click="request()">请求新数据</button>
    <div ng-repeat="user in users track by user.id">
        {{user.name}}
    </div>
		<div>
			  <div>JSON.stringify:{{oldJsonStr}}</div>
			  <div>angular.toJson:{{oldToJson}}</div>
		</div>
	</div>
	<script src="jquery-1.8.3.js"></script>
	<script src="angular1.2.9.js"></script>
	<script src="app.js"></script>
</body>
</html>

这样 ng-repeat 就用将其缓存起来啦,当然可能你的数组元素没有一个标识属性,如果元素数量不多那么可以接受,不然还是建议你手动为其生成一个标识属性。

另外,通过如上在页面上输出JSON.stringify、angular.toJson进一步来看不使用track by和使用track by的效果:

a.不使用track by


b.使用track by


如上运行结果也说明:因为ng-repeat会在数组对象内部添加$$hashkey属性,使用JSON.stringify序列化不会过滤$$hashkey属性,angular.toJson则会过滤掉。

参考文章:http://www.cnblogs.com/MigCoder/p/3930264.html?utm_source=tuicool&utm_medium=referral

AngularJs ng-repeat性能问题

AngularJs ng-repeat性能问题

AngularJs 的 ng-repeat 让我们非常方便的遍历数组生成 Dom 元素,但是使用不当也会有性能问题。

在项目中我们使用 ng-repeat 加载完一个列表后,如果再次请求数据,然后过滤列表,代码可能会这么写:

<div ng-controller="Test">
    <button ng-click="request()">请求新数据</button>
    <div ng-repeat="user in users">
        {{user.name}}
    </div>
</div>

Controller 的代码:

app.controller('Test',function($scope) {
  var users = [];
  for (var i = 0; i < 100; i++) {
    users[i] = {
      id: i,name: "User: " + i
    };
  }
  $scope.users = users;

  $scope.request = function () {
    // 从服务器加载新数据
    var result = [];

    // 直接重新赋值给 users
    $scope.users = result;
  };
});
查看 ng-repeat 的源码可以发现,当 ng-repeat 的数组被替换时,它默认并不会重新利用已有的 Dom 元素,而是直接将其全部删除并重新生成新的数组 Dom 元素:
// 将上次生成的所有 dom 移除
for (key in lastBlockMap) {
  if (lastBlockMap.hasOwnProperty(key)) {
    block = lastBlockMap[key];
    elementsToRemove = getBlockElements(block.clone);
    $animate.leave(elementsToRemove);
    forEach(elementsToRemove,function(element) { element[NG_REMOVED] = true; });
    block.scope.$destroy();
  }
}
Dom 的频繁操作是非常不友好的,为什么 ng-repeat 不能利用已有的 dom 元素去更新数据呢?因为你没有把数组元素的标识属性告诉它,那么两次替换的时候它就没办法追踪了,我们可以看到 ng-repeat 往数组里每个元素加了一个 $$hashKey 的属性:


这个 key 是由 Angular 内部的 nextUid() 方法生成,类似数据库自增,但是是使用字符串。
现在我们明白了,因为每次替换数组都会导致 ng-repeat 为每个元素生成一个新 key,所以根本没办法重用已有的 Dom 元素,那么我们可以使用下边的语法来避免这个问题:

<div ng-controller="Test">
    <button ng-click="request()">请求新数据</button>
  // 使用 track by 标识
    <div ng-repeat="user in users track by user.id">
        {{user.name}}
    </div>
</div>
这样 ng-repeat 就用将其缓存起来啦,当然可能你的数组元素没有一个标识属性,如果元素数量不多那么可以接受, 不然还是建议你手动为其生成一个标识属性

关于angularjs – $interpolate vs ng-repeat和一次性绑定的性能angularjs数据绑定的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于Angular 学习系列 - - $interpolate 和 $parse、AngularJs ng-repeat 必须注意的性能问题、AngularJs ng-repeat必须注意的性能问题、AngularJs ng-repeat性能问题的相关信息,请在本站寻找。

本文标签: