14

假设我有一个对象,其键对应于产品,值对应于对象,这些对象又具有对应于这些产品已售出的价格点的键,以及对应于售出数量的值。

例如,如果我以 1 美元的价格出售 10 个小部件,以 2 美元的价格出售 5 个小部件,我将拥有以下数据结构:

{ 'widget': {'1': 10, '2': 5} }

我想循环这个结构并在一个表中生成行,比如这个:

thing   price  amount
---------------------
widget  $1     10
widget  $2     5

在 Python 中,可以嵌套列表推导来遍历像这样的列表数据结构。使用 ng-repeat 可以实现这样的事情吗?

4

4 回答 4

18

这个怎么样?

http://plnkr.co/edit/ZFgu8Q?p=preview

控制器:

$scope.data = {
  'widget1': {
    '1': 10,
    '2': 5
  },
  'widget2': {
    '4': 7,
    '6': 6
  }
};

看法:

<div ng-controller="MyCtrl">
    <table>
      <thead>
        <tr>
          <td>thing</td>
          <td>price</td>
          <td>amount</td>
        </tr>
      </thead>
      <tbody ng-repeat="(productName, productData) in data">
        <tr ng-repeat="(price, count) in productData">
            <td>{{productName}}</td>
            <td>{{price|currency}}</td>
            <td>{{count}}</td>
        </tr>
      </tbody>
    </table>
</div>

输出:

thing   price   amount
----------------------
widget1 $1.00   10
widget1 $2.00   5
widget2 $4.00   7
widget2 $6.00   6

这将输出tbody每个产品(感谢 Sebastien C 的好主意)。如果需要,您可以区分第一个、中间和最后一个tbody(使用ng-repeat's$first和)并使用$middle(甚至是原生 CSS 选择器,例如-- 我会推荐)设置它们的样式$lastng-class:last-childng-class

于 2013-08-24T01:47:43.593 回答
13

ng-repeat 目前没有可能的方法来复杂地迭代对象内部(在 python 中可能的方式)。查看 ng-repeat源代码并注意匹配的正则表达式为:

(key, value) in collection- 他们推入键数组并分配给值列表,所以你不可能有一个复杂的 ng-repeat 可悲的是......

基本上这里已经回答了两种类型的解决方案:

  1. 嵌套 ng-repeat 就像建议的第一个答案一样。
  2. 像第二个答案建议的那样,重建您的数据对象以适应 1 ng-repeat。

我认为解决方案 2 更好,因为我喜欢将排序和编码逻辑保留在控制器中,而不是在 HTML 文档中处理它。这也将允许更复杂的排序(即基于价格、数量、widgetName 或其他一些逻辑)。

另一件事 - 第二种解决方案将迭代数据集的可能方法(因为hasOwnProperty没有在那里使用)。

我已经改进了这个Plunker中的解决方案(基于 Finishmove Plunker),以便使用 angular.forEach 并表明该解决方案相当简单,但允许复杂的排序逻辑。

$scope.buildData = function() {

  var returnArr = [];

  angular.forEach($scope.data, function(productData, widget) {
      angular.forEach(productData, function( amount, price) {
        returnArr.push( {widgetName: widget, price:price, amount:amount});            
      });
  });
   //apply sorting logic here
  return returnArr;
};
$scope.sortedData = $scope.buildData();

然后在你的控制器中:

<div ng-controller="MyCtrl">
    <table>
      <thead>
        <tr>
          <td>thing</td>
          <td>price</td>
          <td>amount</td>
        </tr>
      </thead>
      <tbody>
      <tr ng-repeat="item in sortedData">
        <td>{{ item.widgetName }}</td>
        <td>{{ item.price|currency }}</td>
        <td>{{ item.amount }} </td>
        </tr>
      </tbody>
    </table>
</div>
于 2013-08-24T13:12:33.067 回答
3

只需将您的对象转换为数组...在 JS 中非常简单。就像是:

$scope.data = { 'widget': { '1': 10, '2': 5 } };

var tableData = [];
for (item in $scope.data) {
    var thing = item;
    for (subitem in $scope.data[thing]) {
        tableData.push({
            thing: thing,
            price: subitem,
            amount: $scope.data[thing][subitem]
        });
    }
}

我用这个例子创建了一个 jsfiddle:http: //jsfiddle.net/b7TYf/

于 2013-08-20T08:50:23.233 回答
1

我使用了一个简单的指令,它具有递归函数来循环我的嵌套对象并创建嵌套元素。这样你就可以保持你的嵌套对象结构。

代码:

angular.module('nerd').directive('nestedItems', ['$rootScope', '$compile', function($rootScope, $compile) {
    return {
        restrict: 'E',
        scope: false,
        link: function(scope, element, attrs, fn) {

            scope.addElement = function(elem, objAr) {

                var ulElement = angular.element("<ul></ul>");

                if (objAr ==  undefined || objAr.length == 0) {
                    return [];
                }

                objAr.forEach(function(arrayItem) {
                    var newElement = angular.element("<li>"+arrayItem.val+"</li>");
                    ulElement.append(newElement);
                    scope.addElement(newElement,arrayItem.sub);
                });

                elem.append(ulElement);
            };
            
            scope.addElement(element,scope.elements);

        }
    };
}]);

我的对象:

$scope.elements = [

      {
          id: 1,
          val: "First Level",
          sub: [

              {
                  id: 2,
                  val: "Second Level - Item 1"
              },
              {
                  id: 3,
                  val: "Second Level - Item 2",
                  sub: [{
                      id: 4,
                      val: "Third Level - Item 1"
                  }]
              }
          ]
      }
  ];

我的 HTML

<nested-items></nested-items>

于 2017-07-03T23:14:15.303 回答