2013-07-10 17 views
9

Tôi đã tìm cách cố gắng viết các bộ lọc nhưng nó khá bực bội.

Dưới đây là một vài tài nguyên Tôi đã sau đây để viết một 'đoạn' lọc

https://groups.google.com/forum/#!topic/angular/IEIQok-YkpU https://groups.google.com/forum/#!topic/angular/gEv1-YV-Ojg

tôi đã cố gắng nó ra với một số thành công. nhưng thấy rằng có sự khác biệt về hành vi giữa các phiên bản

Các phương pháp được mô tả để tạo ra $$ hashKey không hoạt động trong phiên bản 1.1.5. Fiddle đầu tiên là tốt, trong khi thứ hai sản xuất do lỗi lặp, mặc dù mã là giống hệt nhau:

http://jsfiddle.net/nRGTX/38/ - 1.0.3 phiên bản

http://jsfiddle.net/nRGTX/39/ - 1.1.5 phiên bản

Error: 10 $digest() iterations reached. Aborting! 
Watchers fired in the last 5 iterations: [["fn: $watchCollectionWatch; newVal: 16; oldVal: 14"],["fn: $watchCollectionWatch; newVal: 18; oldVal: 16"],["fn: $watchCollectionWatch; newVal: 20; oldVal: 18"],["fn: $watchCollectionWatch; newVal: 22; oldVal: 20"],["fn: $watchCollectionWatch; newVal: 24; oldVal: 22"]] 

Có cách nào để giải quyết vấn đề này không?

Trả lời

12

Bắt đầu với phiên bản 1.1.4 Chỉ thị ng-repeat có đồng hồ trên bộ sưu tập mà bạn đang lặp lại để đảm bảo rằng nó không thay đổi. Cách nó hoạt động là nó so sánh mọi mục trong mảng và nếu các mục không bằng nhau (theo ý nghĩa ===), nó cho rằng bộ sưu tập đã được cập nhật. Ít nhất đây là sự hiểu biết của tôi khi nhìn vào mã.

Nếu bạn đang sử dụng bộ lọc theo nghĩa thông thường, nơi bạn chỉ trả lại một tập con của các mục gốc, thì các mục được trả về sẽ giống nhau mỗi lần. Tuy nhiên, vì bạn đang xây dựng một cấu trúc hoàn toàn mới, các mục trong mảng khác nhau mỗi lần (mặc dù nội dung của chúng giống nhau), vì vậy đồng hồ cho rằng bộ sưu tập liên tục thay đổi.

Giải pháp duy nhất tôi có thể đưa ra là tạo bộ nhớ cache các kết quả được trả về trước đó. Mỗi khi bộ lọc chunk được gọi, nó sẽ kiểm tra xem bạn đã thực hiện một bộ lọc với cùng mảng và chunkSize chưa. Nếu có, nó sẽ trả về kết quả được lưu trong bộ nhớ cache.

Để làm điều này, bạn nên cập nhật chức năng lọc bạn để tìm một cái gì đó như thế này:

return function(array, chunkSize) { 
    if (!(array instanceof Array)) return array; 
    if (!chunkSize) return array; 

    // Create empty cache if it doesn't already exist. 
    if (typeof myApp.chunkCache === "undefined") { 
    myApp.chunkCache = []; 
    } 

    // Search the cache to see if we filtered the given array before. 
    for (var i = 0; i < myApp.chunkCache.length; i++) { 
    var cache = myApp.chunkCache[i]; 
    if (cache.array == array && cache.chunkSize == chunkSize) { 
     return cache.result; 
    } 
    } 

    // If not, construct the chunked result. 
    var result = chunkArray(array, chunkSize); 
    defineHashKeys(result); 

    // And then add that result to the cache. 
    var cache = { 
    array: array, 
    chunkSize: chunkSize, 
    result: result 
    }; 
    myApp.chunkCache.push(cache); 

    return result; 
} 

Tôi cũng nên chỉ ra rằng bạn có thể có thể loại bỏ các defineHashKeys cuộc gọi, bởi vì tôi không nghĩ rằng nó phục vụ bất kỳ mục đích trong mã này. Tôi chỉ để lại nó bởi vì nó nằm trong mã ban đầu của bạn. Nó dường như không tạo ra bất kỳ sự khác biệt nào khi tôi gỡ bỏ nó.

+0

Cảm ơn James! Với bộ nhớ cache ... điều gì xảy ra nếu có nhiều bộ lọc đoạn trên trang? Tôi đã làm một thử nghiệm nhỏ ở đây http://jsfiddle.net/nRGTX/42/ và nó có vẻ làm việc cho bộ lọc 2 đoạn nhưng tôi tự hỏi tại sao đây là trường hợp như tôi đã có thể mong đợi các bộ lọc để clobber mỗi khác – zcaudate

+0

tôi đã thử nghiệm với nhiều bộ lọc - giải pháp được thiết kế để hoạt động như vậy. Lưu ý rằng bộ nhớ cache lưu trữ một mục riêng biệt cho mỗi kết hợp của mảng và chunkSize, do đó, hai bộ lọc có kích thước khác nhau hoặc các mảng khác nhau không nên xung đột. –

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