2013-04-20 35 views
79

Tôi mới sử dụng Angular.js và có một số vấn đề khi sắp xếp mảng của mình và làm việc trên dữ liệu được sắp xếp đó.

Tôi có một danh sách có các mục và muốn sắp xếp nó theo "Store.storeName", hiện đang hoạt động. Nhưng sau khi sắp xếp dữ liệu, chức năng xóa của tôi không hoạt động nữa. Tôi nghĩ thats vì chỉ số $ là sai sau khi sắp xếp, và do đó, các dữ liệu sai sẽ bị xóa.

Tôi làm cách nào để giải quyết vấn đề này? Đặt hàng dữ liệu trong phạm vi chứ không phải trong chế độ xem? Làm thế nào để làm điều đó?

Dưới đây là một số mã có liên quan:

Trong Xem:

<tr ng-repeat="item in items | orderBy:'Store.storeName'"> 
       <td><input class="toggle" type="checkbox" ng-model="item.Completed"></td> 
       <td>{{item.Name}}</td> 
       <td>{{item.Quantity}} Stk.</td> 
       <td>{{item.Price || 0 | number:2}} €</td>     
       <td>{{item.Quantity*item.Price|| 0 | number:2}} €</td> 
       <td>{{item.Store.storeName}}</td> 
       <td><a><img src="img/delete.png" ng-click="removeItem($index)">{{$index}}</a></td> 
      </tr> 

Và trong bộ điều khiển của tôi, tôi có chức năng, mà nên xóa các dữ liệu cụ thể này xóa:

$scope.removeItem = function(index){ 
     $scope.items.splice(index,1); 
    } 

này hoạt động tốt trước khi đặt hàng trong Chế độ xem. Nếu điều gì đó quan trọng bị thiếu, vui lòng cho tôi ngay bây giờ.

Cảm ơn!

Trả lời

128

Thay vào đó hoặc chuyển tiếp trên $index - mà - như bạn đã nhận thấy - sẽ trỏ đến các chỉ mục trong một mảng được sắp xếp/lọc, bạn có thể vượt qua các mục riêng của mình để chức năng removeItem của bạn:

<a><img src="img/delete.png" ng-click="removeItem(item)">{{$index}}</a> 

và sửa đổi các removeItem chức năng để tìm một chỉ số sử dụng phương pháp indexOf của một mảng như sau:

$scope.removeItem = function(item){ 
    $scope.items.splice($scope.items.indexOf(item),1); 
} 
+0

Wow cảm ơn bạn, công trình này hoàn hảo! – FuzzBuzz

+1

@ pkozlowski.opensource Bạn là một thiên tài! Bạn có thể vượt qua một mục, không chỉ mục .. Wow !! Cảm ơn người đàn ông. –

+0

Chỉ mục mảngOf không khả dụng trong Internet Explorer 8 trở xuống. –

3

Hãy thử điều này:

$scope.remove = function(subtask) { 

    var idx = $scope.subtasks.indexOf(subtask), 
     st = $scope.currentTask.subtasks[idx]; 

    // remove from DB 
    SubTask.remove({'subtaskId': subtask.id}); 

    // remove from local array 
    $scope.subtasks.splice(idx,1); 

} 

Bạn có thể tìm thấy giải thích chi tiết trong this entry trong blog của mình.

+0

Sẽ bỏ phiếu xuống cho câu trả lời chỉ liên kết nếu tôi có thể. – ankr

18

Tôi gặp vấn đề tương tự và các câu trả lời khác trong chủ đề này không phù hợp với hoàn cảnh của tôi.

Tôi đã giải quyết vấn đề của tôi với bộ lọc tùy chỉnh:

angular.module('utils', []).filter('index', function() { 
    return function (array, index) { 
     if (!index) 
      index = 'index'; 
     for (var i = 0; i < array.length; ++i) { 
      array[i][index] = i; 
     } 
     return array; 
    }; 
}); 

mà có thể được sử dụng theo cách này:

<tr ng-repeat="item in items | index | orderBy:'Store.storeName'"> 

và sau đó trong HTML bạn có thể sử dụng item.index thay vì $index.

Phương pháp này phù hợp cho các bộ sưu tập đối tượng. Vui lòng lưu ý rằng bộ lọc tùy chỉnh này phải là bộ lọc đầu tiên trong danh sách tất cả các bộ lọc được áp dụng (orderBy, v.v.) và nó sẽ thêm thuộc tính bổ sung index (tên có thể tùy chỉnh) vào mỗi đối tượng của bộ sưu tập.

+0

Bạn có thể giải thích tại sao các câu trả lời khác không phù hợp với hoàn cảnh của bạn không? –

+1

@ pkozlowski.opensource Điều này sạch hơn rất nhiều. Ngoài ra tùy thuộc vào những sự kiện có thể được đính kèm, và sự phức tạp của các mục trong indexOf đến nay hiệu quả hơn rất nhiều. Ngoài ra '$ scope.items.splice ($ scope.items.indexOf (item), 1);' sẽ không hoạt động như mong đợi cho các mục trùng lặp. – martin

+1

@martin bạn nên sao lưu các tuyên bố của mình về hiệu suất với số thực. Một bộ lọc có _huge_ bất lợi khi được thực hiện trên _each và every_ $ digest cycle vì vậy tôi không nghĩ rằng nó giúp với hiệu suất ... –

1

Tôi vừa để lại nhận xét, nhưng tôi không có "danh tiếng".

giải pháp của dặm chính xác là những gì tôi cần. Để trả lời pkozlowski.câu hỏi của opensource: khi bạn có một danh sách động (ví dụ: nơi bạn cho phép xóa), hoặc cả hai (trường hợp của tôi), sử dụng $index không hoạt động vì nó sẽ là chỉ mục sai cho dữ liệu phía sau phân loại và sử dụng ngInit để cache giá trị không hoạt động vì nó không được đánh giá lại khi danh sách thay đổi.

Lưu ý rằng giải pháp dặm cho phép đối với tên thuộc tính chỉ số gắn liền với thể được tùy chỉnh bằng cách thông qua một tham số <tr ng-repeat="item in items | index:'originalPosition' | orderBy:'Store.storeName'">

phiên bản tinh chỉnh của tôi:

.filter('repeatIndex', function repeatIndex() 
{ 
// This filter must be called AFTER 'filter'ing 
// and BEFORE 'orderBy' to be useful. 
    return(function(array, index_name) 
    { 
     index_name = index_name || 'index'; 
     array.forEach(function(each, i) 
     {each[ index_name ] = i;}); 
     return(array); 
    }); 
}) 
15

tôi bắt đầu tìm hiểu góc và phải đối mặt với rắc rối tương tự, và dựa trên câu trả lời của @ pkozlowski-opensource, tôi đã giải quyết nó chỉ với một cái gì đó như

<a> 
    <img src="img/delete.png" ng-click="removeItem(items.indexOf(item))"> 
    {{items.indexOf(item)}} 
</a> 
+0

Điều này là tốt nhất và đơn giản hơn là tạo bộ lọc tùy chỉnh, v.v. +1 –

+0

đây không phải là câu trả lời đúng? Điều này giải quyết được vấn đề của tôi –

-2

Trong trường hợp ai đó cần sử dụng $index, bạn có thể đặt tên cho mảng được sắp xếp/lọc:

<tr ng-repeat="item in sortedItems = (items | orderBy:'Store.storeName') track by $index"> 

Xem câu trả lời của tôi here.

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