简体   繁体   English

angularjs-动态函数返回

[英]angularjs - dynamic function return

index.html index.html

<div ng-repeat="object in objects" ng-style="getStyle(object.id)"></div>

controller.js controller.js

[...]

$scope.startWidth = 100;

$scope.getObject = [...]

$scope.getStyle = function(id) {
   var widthVal = $scope.startWidth;
   $scope.StartWidth += $scope.getObject(id).value;
   return { width : widthVal }
}

[...]

This code runs into an infinite $digest loop. 此代码遇到无限的$ digest循环。 I think i know why. 我想我知道为什么。 The return value should not to be dynamic. 返回值不应是动态的。 But how can i realize that without the loop? 但是我怎么能意识到没有循环呢? I want to display objects with different width. 我想显示不同宽度的对象。 The width of an object depends on a value of the previous object. 对象的宽度取决于前一个对象的值。

The problem is that ng-style puts a $watchExpression on each child scope. 问题在于ng-style在每个子范围上都放置了一个$watchExpression

A $watchExpression must be idempotent , means it must return the same with multiple checks. $watchExpression必须是幂等的 ,这意味着它必须通过多次检查返回相同的值。
If a $watchExpression is still dirty another $digest will be triggered. 如果$watchExpression 仍然很脏,则会触发另一个$digest

UPDATE 更新

After I saw GRaAL nice answer I came up with even better solution: 在看到GRaAL好的答案后,我想出了一个更好的解决方案:

Here is a demo plunker: http://plnkr.co/edit/oPrTiwTOyCR3khs2iVga?p=preview 这是一个演示插件: http ://plnkr.co/edit/oPrTiwTOyCR3khs2iVga?p=preview

controller: 控制器:

$scope.$watchCollection('objects', function calculateWidths() {
  var tempWidth = 0;
  for( var i = 0; i < $scope.objects.length; i++) {
    tempWidth += $scope.objects[i].value;
    $scope.objects[i].width = tempWidth + 'px';
  }
});

markup: 标记:

<div ng-repeat="object in objects" ng-style="{width: object.width}">

old solution 旧解决方案

Here is a plunker: http://plnkr.co/edit/CqxOmV5lpZSLKxqT4yqo?p=preview 这是一个小矮人: http ://plnkr.co/edit/CqxOmV5lpZSLKxqT4yqo?p=preview

I agree with Ilan's problem description and solution - it works in case the objects array is not going to change, otherwise the widths will be calculated incorrectly. 我同意Ilan的问题描述和解决方案-它可以在objects数组不改变的情况下起作用,否则宽度将被错误地计算。 If new objects may be added/removed in runtime then it is better to recalculate the widths when the collection is changed (see $watchCollection method of scope) or on each digest cycle (for short list of elements it shall be fast enough), something like that: 如果可以在运行时添加/删除新对象,则最好在更改集合时(参见作用域的$watchCollection方法)或在每个摘要周期(对于元素的简短列表,应足够快)重新计算宽度。像那样:

  var widths = [];
  $scope.$watch(function calculateWidths() {
    var tempWidth = 0;
    widths = [];
    angular.forEach($scope.objects, function(obj) {
      tempWidth += obj.value;
      widths.push(tempWidth);
    });
  });

  $scope.getStyle = function(idx){
    return {width: widths[idx] + 'px'}
  }

Here is the plunker 这是the子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM