Bạn đang tìm kiếm để thực hiện ba hoạt động:
- Lấy mảng thẻ từ mỗi mục trong
$scope.list
- Flatten này vào một mảng đơn
- Lấy giá trị duy nhất từ mảng này
Bạn có thể làm điều này với JavaScript thuần túy, nhưng để giúp mọi thứ trở nên dễ dàng hơn, tôi khuyên bạn nên sử dụng Underscore, thư viện cung cấp cho bạn quyền truy cập vào nhiều nội dung thú vị ctions để thao tác và kiểm tra mảng, đối tượng, v.v.
Hãy bắt đầu với mã này:
$scope.list = [
{id: 0, tags: ['tag1', 'tag2']},
{id: 1, tags: ['tag2']},
{id: 2, tags: ['tag1', 'tag3', 'tag4']},
{id: 3, tags: ['tag3', 'tag4']}
];
Bây giờ, chúng ta hãy thực hiện các hoạt động đầu tiên: có được các mảng từ tags
sở hữu đối với từng đối tượng trong $scope.list
. Dấu gạch dưới cung cấp phương thức pluck
, đó chỉ là những gì chúng ta cần.
nhổ_.pluck(list, propertyName)
Một phiên bản thuận tiện về những gì có lẽ là trường hợp sử dụng phổ biến nhất cho bản đồ: chiết xuất một danh sách các giá trị tài sản.
Sử dụng nhổ, chúng ta có thể nhận được như sau:
var tags = _.pluck($scope.list, 'tags');
// gives us [['tag1', 'tag2'], ['tag2'], ['tag1', 'tag3', 'tag4'], ['tag3', 'tag4']]
Bây giờ, chúng tôi muốn flatten mảng đó.
flatten_.flatten(array, [shallow])
flattens một mảng lồng nhau (làm tổ có thể đến bất kỳ độ sâu). Nếu bạn vượt qua nông, mảng sẽ chỉ được san bằng một mức duy nhất.
tags = _.flatten(tags);
// gives us ['tag1', 'tag2', 'tag2', 'tag1', 'tag3', 'tag4', 'tag3', 'tag4']
Cuối cùng, bạn chỉ muốn một phiên bản của mỗi thẻ.
uniq_.uniq(array, [isSorted], [iterator])
Bí danh: unique
Tạo một phiên bản trùng lặp miễn phí của mảng, sử dụng === để kiểm tra sự bình đẳng đối tượng. Nếu bạn biết trước rằng mảng được sắp xếp, chuyển đúng cho isSorted sẽ chạy một thuật toán nhanh hơn nhiều.Nếu bạn muốn tính toán các mục duy nhất dựa trên một phép biến đổi, hãy chuyển một hàm lặp.
tags = _.unique(tags)
// gives us ['tag1', 'tag2', 'tag3', 'tag4']
Chúng ta có thể kết hợp các cùng với chain
phương pháp hữu ích gạch để chuỗi này lại với nhau. Hãy tạo một hàm trên phạm vi mà trả về thẻ duy nhất:
$scope.uniqueTags = function() {
return _.chain($scope.list)
.pluck('tags')
.flatten()
.unique()
.value();
};
Do đây là một chức năng, nó sẽ luôn luôn trả lại thẻ độc đáo, không có vấn đề nếu chúng ta thêm hoặc loại bỏ các mục trong $scope.list
sau khi thực tế.
Bây giờ bạn có thể sử dụng ng-repeat
trên uniqueTags
để hiển thị mỗi thẻ:
<div ng-repeat="tag in uniqueTags()">
<label class="checkbox">
<input type="checkbox" ng-model="filter.tag" />
{{tag}}
</label>
</div>
Đây là một jsFiddle làm việc thể hiện kỹ thuật này: http://jsfiddle.net/BinaryMuse/cqTKG/
Hoàn hảo! Và một lời giải thích tuyệt vời là tốt! –
Cảm ơn! Rất vui khi được giúp đỡ.^_^ –
Hiệu suất như thế nào khi sử dụng chức năng tổng hợp như vậy? Bao lâu thì Angular sẽ gọi hàm này? – oldwizard