2013-02-19 69 views
47

Giả sử tôi có người dùng sau:Làm thế nào để sắp xếp nguồn dữ liệu đối tượng trong ng-lặp trong AngularJS?

$scope.users = { 
    "2": { 
    email: '[email protected]', 
    name: 'John' 
    }, 
    "3": { 
    email: '[email protected]', 
    name: 'Elisa' 
    } 
} 

Tôi muốn tạo ra một <select> với các tùy chọn sau:

<option value="3">Elisa</option> 
<option value="2">John</option> 

Nói cách khác, người sử dụng nên được sắp xếp theo tên.

Tôi đã thử các sau đây bằng cách sử dụng cú pháp (key, value) in expression, nhưng nó không hoạt động:

<option ng-repeat="(user_id, user) in users | orderBy:'user.name'" 
     value="{{ user.id }}"> 
    {{ user.name }} 
</option> 

Live example here.

tôi thiếu gì?

Vui lòng không đề xuất giải pháp với ng-options khi tôi sử dụng ui-select2 không tương thích với ng-options.

+0

Chúng ta không cần hai thẻ mới cho câu hỏi này và câu hỏi này mà thôi. Hãy làm cho các thẻ có lợi bằng cách thêm một wiki thích hợp và thêm chúng vào các câu hỏi có liên quan khác. Nếu bạn không thể tìm thấy các câu hỏi khác cho các thẻ, thì chúng không cần phải tồn tại hai lần trên ... – Charles

+2

'ng-repeat' và' orderBy' là những thứ rất phổ biến trong AngularJS. Tôi tin rằng sẽ có nhiều câu hỏi hơn về hai điều này.Nhưng, dù sao, tôi đã thêm các thẻ này vào một số câu hỏi khác. –

+0

Vì tôi thiếu uy tín để chính thức đề xuất cách viết thẻ thay thế, người khác ở đây nên thêm ** angularjs-order-by **. Có vẻ như vô nghĩa rằng con lạc đà đã đặt 'ngRepeat' sẽ trở thành' ng-repeat', trong khi 'orderBy' trở thành' orderby'. – maurice

Trả lời

52

Trong khi bạn sẽ thấy điều này trong các chủ đề tài liệu tham khảo câu trả lời của tác giả trong một liên kết, tôi nghĩ rằng nó sẽ là tốt để đưa lên một trong những cách giải quyết đề cập Đúng là điều này không được thực hiện về mặt kỹ thuật, nhưng có một công việc dễ dàng xung quanh nếu bạn sẵn sàng thay đổi mô hình dữ liệu của mình một chút: sử dụng bộ lọc tùy chỉnh để tạo một mảng các thuộc tính của đối tượng (mà không cần thay thế). Nếu bạn thêm các lĩnh vực trọng điểm để các đối tượng ("id" trong trường hợp ở trên), bạn sẽ có thể để có được hành vi của mình tìm kiếm

app.filter("toArray", function(){ 
    return function(obj) { 
     var result = []; 
     angular.forEach(obj, function(val, key) { 
      result.push(val); 
     }); 
     return result; 
    }; 
}); 
... 

$scope.users = { 
    1: {name: "John", email: "[email protected]", id: 1}, 
    2: {name: "Elisa", email: "[email protected]", id: 2} 
}; 

Dưới đây là chỉ thị ng-repeat mà có thể được sử dụng:

<option value="{{user.id}}" ng-repeat="user in users | toArray | orderBy:'name'">{{user.name}}</option> 

Và đây là plunkr.

Lưu ý rằng bộ lọc orderBy mất name làm thông số của nó chứ không phải user.name.

Thật không may, việc thêm thuộc tính id vào đối tượng của bạn sẽ tạo ra khả năng không phù hợp với khóa của nó trong đối tượng chứa.

Trong liên kết bạn đã đề cập trong câu trả lời, cũng có các giải pháp đề xuất tạo thuộc tính id trong đối tượng người dùng, nhưng tôi cảm thấy cách tiếp cận này hơi lộn xộn hơn một chút (với chi phí giới thiệu sao chép dữ liệu).

+0

@BarthZalewski Điều này có vẻ tốt tuy nhiên làm thế nào đến nếu tôi cố gắng đảo ngược bộ lọc không có gì thay đổi? bạn có thể xử lý ngược lại i n cuh như một tình huống? ng-repeat = "người dùng trong người dùng | toArray | orderBy: 'name': reverse" – ak85

+0

Điều này cũng hoạt động khi sử dụng (khóa, giá trị) trong cách tiếp cận của người dùng. Làm tốt! –

+1

Để trả lời câu hỏi của @ ak85, bạn sẽ sử dụng ng-repeat = "user in users | toArray | orderBy: 'name': true" để đảo ngược danh sách. Boolean true xác định thứ tự ngược lại. – Doug

9

OK, tôi tìm thấy câu trả lời:

It is not implemented yet :(

+9

Nó cũng có thể đáng nói đến là không có kế hoạch để thực hiện nó hoặc theo các chủ đề bạn trích dẫn. – mhess

0

Thêm vào câu trả lời chấp nhận và nhìn thấy định dạng dữ liệu của bạn, bạn nên chuyển đổi dữ liệu của bạn như

app.filter('myFilterUsers',function(){ 
    return function(data) 
    { 
     var newRes = []; 
     angular.forEach(data,function(val,key){ 
      val["id"] = key; //Add the ID in the JSON object as you need this as well. 
      newRes.push(val); 
     }); 
     return newRes; 
    } 
}); 
Các vấn đề liên quan