像"变量"在AngularJS?

时间:2015-02-14 12:30:14

标签: angularjs

样本控制器数据:

$scope.items = [{ id: 1, name: 'First'}, { id: 2, name: 'Second'}];

是否有一些角度来使下面的代码像"变量"?

<ul>
    <li data-ng-repeat="items">{{id}} {{name}}</li>
</ul>

而不是:

<ul>
    <li data-ng-repeat="i in items">{{i.id}} {{i.name}}</li>
</ul>

请随意提出更易理解的标题/问题。

3 个答案:

答案 0 :(得分:0)

参考Angular ngRepeat document,目前只支持以下表达式。

  1. 表达式中的变量
  2. (表达式中的键,值)
  3. 通过tracking_expression
  4. 表达式跟踪中的变量
  5. 表达式中的变量为alias_expression
  6. 这意味着,您不能简单地使用ng-repeat="items"来迭代集合。

    BTW,ng-repeat将为每个元素创建一个单独的范围,并将variable(key, value)绑定到新创建的范围。所以你所指的“变量”并不是Angular内置的。您需要为此功能创建自定义指令。

答案 1 :(得分:0)

我的首选答案是“不要这样做”,但没有做到这一点,因为它很有意思,这里是一个概念证明,由this question辅助,大部分改编自this blog post

app.directive('myRepeat', function(){
  return {
    transclude : 'element',
    compile : function(element, attrs, linker){
      return function($scope, $element, $attr){
        var collectionExpr = attrs.myRepeat;
        var parent = $element.parent();
        var elements = [];

        // $watchCollection is called everytime the collection is modified
        $scope.$watchCollection(collectionExpr, function(collection) {
          var i, block, childScope;

          // check if elements have already been rendered
          if(elements.length > 0){
            // if so remove them from DOM, and destroy their scope
            for (i = 0; i < elements.length; i++) {
              elements[i].el.remove();
              elements[i].scope.$destroy();
            };
            elements = [];
          }

          for (i = 0; i < collection.length; i++) {
            // create a new scope for every element in the collection.
            childScope = $scope.$new();

            // ***
            // This is the bit that makes it behave like a `with` 
            // statement -- we assign the item's attributes to the
            // child scope one by one, rather than simply adding
            // the item itself.
            angular.forEach(collection[i], function(v, k) {
              childScope[k] = v;
            });
            // ***

            linker(childScope, function(clone){
              // clone the transcluded element, passing in the new scope.
              parent.append(clone); // add to DOM
              block = {};
              block.el = clone;
              block.scope = childScope;
              elements.push(block);
            });
          };
        });
      }
    }
  }
});

然后这会做你想要的:

app.controller("myController", function($scope, $http) {
  $scope.items = [
    {a: 123, b: 234},
    {a: 321, b: 432}
  ];
});

使用您想要的HTML结构:

<div ng-controller="myController">
  <ul>
    <li my-repeat="items">
      {{ a }} {{ b }}
    </li>
  </ul>
</div>

请注意,如果将属性复制到子作用域而不是引用,如果对视图进行了更改,它们将不会影响模型(即父items列表),严重限制了该指令的用处。你可以用一个额外的scope.$watch来解决这个问题,但使用ng-repeat几乎肯定不会像通常那样使用它。

答案 2 :(得分:0)

我无法理解为什么其他用户会告诉您,您需要通过新指令完成所需操作。这是一个工作片段。

angular.module("Snippet",[]).controller("List",["$scope",function($scope){
    $scope.items = [{ id: 1, name: 'First'}, { id: 2, name: 'Second'}];
  }]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="Snippet" ng-controller="List as list">

  <ul>
    <!-- Iterating the array -->
    <li ng-repeat="item in items">
      <!-- Iterating each object of the array -->
      <span ng-repeat="(key,value) in item">{{value}} </span>
    </li>
  </ul>
  
</body>

简单地说,您需要通过ng-repeat迭代数组的元素,然后您可以使用检索到的对象item执行您想要的操作。如果您想显示其值,例如,正如您的问题所示,那么新的ng-repeat可以完成工作。