2015-02-02 20 views
10

Tôi có một đối tượng JSON, đại diện như vậy:Góc ng-lặp lại với các đối tượng json lồng nhau?

{ 
    "orders" : [ 
    { 
     "ordernum" : "PRAAA000000177800601", 
     "buyer" : "Donna Heywood" 
     "parcels" : [ 
     { 
      "upid" : "UPID56789", 
      "tpid" : "TPID789456789485" 
     }, 
     { 
      "upid" : "UPID586905486090", 
      "tpid" : "TPID343454645455"   
     } 
     ] 
    }, 
    { 
     "ordernum" : "ORAAA000000367567345", 
     "buyer" : "Melanie Daniels" 
     "parcels" : [ 
     { 
      "upid" : "UPID456547347776", 
      "tpid" : "TPID645896579688" 
     }, 
     { 
      "upid" : "UPID768577673366", 
      "tpid" : "TPID784574333345" 
     } 
     ] 
    } 
    ] 
} 

tôi cần phải làm một repeater ngày thứ hai mức điều này, một danh sách các số điện thoại "upid".

Tôi biết đã làm thế nào để có được các cấp cao nhất

<li ng-repeat="o in orders">{{o.ordernum}}</li>

Nhưng tôi không rõ ràng về trình tự để lặp một mức độ xuống. Ví dụ, đây là sai:

Tôi cũng biết làm thế nào để tổ lặp để có được điều này, nhưng trong trường hợp này tôi không cần để hiển thị các cấp cao nhất ở tất cả.

Làm rõ

Mục tiêu ở đây là phải có một danh sách với 4 "upid" số (có 2 theo từng thửa, và có 2 bưu kiện theo thứ tự).

Trả lời

0

Tìm kiếm rất nhiều giải pháp tốt và đơn giản để lặp động. Tôi đã đưa ra điều này

JAVASCRIPT (góc cạnh): một người là một ví dụ về đối tượng lồng nhau. Hàm is_object sẽ được sử dụng trong chế độ xem HTML.

$scope.person = { 
    "name": "john", 
    "properties": { 
     "age": 25, 
     "sex": "m" 
    }, 
    "salary": 1000 
} 

// helper method to check if a field is a nested object 
$scope.is_object = function (something) { 
    return typeof (something) == 'object' ? true : false; 
}; 

HTML: xác định mẫu cho bảng đơn giản. TD đầu tiên là khóa được hiển thị. một TD (2 hoặc 3, nhưng không bao giờ cả hai) sẽ được hiển thị giá trị nếu nó không phải là một đối tượng (số/chuỗi), OR lặp lại nếu một đối tượng của nó.

<table border="1"> 
<tr ng-repeat="(k,v) in person"> 
    <td> {{ k }} </td> 
    <td ng-if="is_object(v) == false"> {{ v }} </td> 
    <td ng-if="is_object(v)"> 
     <table border="1"> 
      <tr ng-repeat="(k2,v2) in v"> 
       <td> {{ k2 }} </td> 
       <td> {{ v2 }} </td> 
      </tr> 
     </table> 
    </td> 
</tr> 
</table> 
4

Có vẻ như bạn chỉ cần một đôi lồng nhau vòng lặp for -

<ul>  
    <div ng-repeat="o in orders"> 
    <li ng-repeat="p in o.parcels">{{p.upid}}</li> 
    </div> 
</ul> 

HTML có thể là một chút xấu xí ở đây, nhưng tôi không chắc chắn chính xác những gì bạn đang cho. Hoặc bạn chỉ có thể tạo một mảng mới của parcels thông qua ánh xạ.

+0

Câu trả lời đó sẽ cho tôi 2 uls, mỗi câu trả lời có 2 LI. – Steve

+0

Tôi đang tìm cách tạo một UL với 4 bưu kiện. – Steve

+0

@Steve Như tôi đã nói, tôi không biết cụ thể bạn muốn đầu ra như thế nào. Ngoài ra, bạn luôn có các tùy chọn ánh xạ tới một mảng mới. –

5

Bạn chỉ có thể tạo mới mảng 'thửa' như trong bản demo dưới đây:

var app = angular.module('app', []); 
 
app.controller('homeCtrl', function($scope) { 
 
    $scope.data = { 
 
    "orders": [{ 
 
     "ordernum": "PRAAA000000177800601", 
 
     "buyer": "Donna Heywood", 
 
     "parcels": [{ 
 
     "upid": "UPID56789", 
 
     "tpid": "TPID789456789485" 
 
     }, { 
 
     "upid": "UPID586905486090", 
 
     "tpid": "TPID343454645455" 
 
     }] 
 
    }, { 
 
     "ordernum": "ORAAA000000367567345", 
 
     "buyer": "Melanie Daniels", 
 
     "parcels": [{ 
 
     "upid": "UPID456547347776", 
 
     "tpid": "TPID645896579688" 
 
     }, { 
 
     "upid": "UPID768577673366", 
 
     "tpid": "TPID784574333345" 
 
     }] 
 
    }] 
 
    }; 
 

 
    $scope.parcels = []; 
 
    angular.forEach($scope.data.orders, function(order) { 
 
    angular.forEach(order.parcels, function(parcel) { 
 
     $scope.parcels.push(parcel) 
 
    }) 
 
    }) 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="app"> 
 
    <div ng-controller="homeCtrl"> 
 

 
    <ul> 
 
     <li ng-repeat="o in parcels">{{o.upid}}</li> 
 
    </ul> 
 

 
    </div> 
 
</div>

+0

Điều này không làm việc với dữ liệu được tải bên ngoài, hãy xem http://plnkr.co/edit/2WnMcwxcmTVA8luquWM9? p = xem trước vì '$ scope.data.orders' không tồn tại sau đó. Tôi đang tải các đơn hàng thông qua một nhà máy. – Steve

+0

Điều này sẽ vẫn hoạt động ngay cả khi tải dữ liệu từ nhà máy. Bạn chỉ cần ánh xạ mảng mới khi dữ liệu được nhập. Giữ biến scoped giống nhau, sau đó chỉ cần thay đổi biến đó thành mảng mới khi dữ liệu được nhập. Chỉnh sửa: Đây là cách tốt nhất để làm điều đó, các câu trả lời khác là không cần thiết nặng và/hoặc không hoạt động. – ribsies

+0

@Steve vui lòng xem tại đây http://plnkr.co/edit/FXpgRDqQTAm6QUstI86z?p=preview – sylwester

0

Lý do mà không làm việc theo cách bạn mong đợi là do mảng bưu kiện là một đối tượng bên trong mỗi thứ tự riêng lẻ trong mảng đặt hàng của bạn, tức là nó không phải là một đối tượng của mảng đơn đặt hàng.

Nếu đơn đặt hàng của bạn mảng được xác định trên $ phạm vi của một bộ điều khiển, sau đó bạn tạo ra các mảng trên biến $scope:

$scope.allParcels = $scope.orders 
    .map(function (elem) { 
     return elem.parcels; 
    }) // get an array where each element is an array of parcels. 
    .reduce(function (previousValue, currentValue) { 
     return previousValue.concat(currentValue); 
    }); // concat each array of parcels into a single array of parcels 

sau đó trên mẫu, bạn có thể sử dụng <li ng-repeat='p in allParcels'>{{p.upid}}</li>

Nếu, tuy nhiên, bạn không muốn đặt mảng vào số $scope, tôi tin rằng bạn có thể làm điều gì đó tương tự như sau:

<li ng-repeat="p in orders 
    .map(function (elem) { 
     return elem.parcels; 
     }) 
    .reduce(function (previousValue, currentValue) { 
      return previousValue.concat(currentValue); 
    })">{{p.upid}}</li> 

althoug h Tôi không chắc chắn rằng Angular sẽ đánh giá .map/.reduce trong biểu thức ng-repeat (cũng có một mảng được tạo theo cách này trong một ng-repeat là không được thông báo vì góc sẽ phải liên tục tạo ra một mảng mới thông qua bản đồ/giảm trên mỗi chu kỳ $digest).

+0

Rất tiếc. Điều đó cực kỳ phức tạp. Nhưng nhờ lời giải thích chi tiết, tôi không biết. – Steve

5

Trên thực tế cùng một câu trả lời của @sylwester. Cách tốt nhất để đặt nó trong filter. Và bạn có thể tái sử dụng nó bằng cách truyền tham số propertyName.

Trong trường hợp của bạn, chúng tôi đã thông qua parcels

JS

myApp.filter('createarray', function() { 
    return function (value, propertyName) { 
     var arrayList = []; 
     angular.forEach(value, function (val) { 
      angular.forEach(val[propertyName], function (v) { 
       arrayList.push(v) 
      }); 
     }); 
     return arrayList; 
    } 
}); 

HTML

<ul> 
    <li ng-repeat="o in ordersList.orders | createarray: 'parcels'">{{o.upid}}</li> 
</ul> 

Đây là working Fiddle

Các vấn đề liên quan