2013-06-22 14 views
6

Tôi muốn tải toàn bộ bộ sưu tập và sau đó chỉ bóc các bản ghi để sử dụng làm mô hình một lần, mà không phải thực hiện một lần tới máy chủ mỗi lần .Model.find(). Sau đó() kích hoạt trước khi các bản ghi thực sự được tải

Tôi đã tìm hiểu cách sử dụng Ember.Deferred để trả lại lời hứa, nhưng tôi không thể có được lời hứa để giải quyết vào đúng thời điểm. Mã sau đây chỉ xuất ra "Đã tìm thấy 0" bao giờ:

App.PersonRoute = Ember.Route.extend({ 
    model: function(params) { 
    var name = "Erik"; 
    var promise = Ember.Deferred.create(); 
    App.people = App.Person.find(); 

    App.people.then(function() { 
     console.log('Found ' + App.people.get('length')); 
     var person = App.people.findProperty('name', name) 
     promise.resolve(person); 
    }); 

    return promise; 
    } 
}); 

Nếu tôi quấn phần thân của() trong một setTimeout và đợi vài giây, mọi thứ hoạt động tốt.

Có sự kiện nào khác mà tôi có thể liên kết bằng cách nào đó không? Tôi đã thử App.people.on ('isLoaded'), nhưng isLoaded luôn đúng.

Cảm ơn!

Trả lời

6

Có sự kiện nào khác mà tôi có thể liên kết bằng cách nào đó không?

Thực tế có sự kiện bạn có thể nghe và đó là didLoad.

Tôi đã thử App.people.on ('isLoaded'), nhưng isLoaded luôn đúng.

Đối với isLoaded đã có rất nhiều nhầm lẫn về điều này, xem here ví dụ, sự nhầm lẫn xuất phát từ thực tế là cờ isLoaded được thiết lập là true do thiết kế khi các cửa hàng đã hoàn tất tải RecordArray cho các bản ghi, ngay cả khi ban đầu trống vì không có bản ghi nào đã có sẵn cục bộ. Sau đó, khi yêu cầu đến máy chủ quay trở lại, RecordArray sẽ được điền bằng các bản ghi nhận được từ chương trình phụ trợ và các ràng buộc sẽ bắt đầu và các mẫu của bạn được cập nhật.

Như đã nêu trong guides:

Một kỷ lục đó là cả hai phương tiện tải và sạch sẽ đó là đã nhận được thông tin về các thuộc tính và các mối quan hệ từ máy chủ của nó, và không có thay đổi đã được thực hiện tại địa phương trên máy khách.

Đã được nêu ở trên là điều làm cho didLoad kích hoạt.

Để biết thêm các sự kiện mô hình liên quan bạn có thể nghe có một cái nhìn tại các hướng dẫn dưới model lifecycle

Bây giờ để thiết lập của bạn, bạn có thể viết lại mã của bạn để một cái gì đó như thế này:

App.PersonRoute = Ember.Route.extend({ 
    model: function(params) { 
    var name = "Erik"; 
    var promise = Ember.Deferred.create(); 
    App.people = App.Person.find(); 

    App.people.on('didLoad', function() { 
     console.log('Found ' + App.people.get('length')); 
     var person = App.people.findProperty('name', name) 
     promise.resolve(person); 
    }); 

    return promise; 
    } 
}); 

Hy vọng nó giúp .

2

Nếu lời hứa không được giải quyết vào đúng thời điểm, tôi nghĩ đó sẽ là một lỗi (khá lớn) trong Ember/dữ liệu. Tôi sẽ đề nghị điền một lỗi với Emberjs/dữ liệu.

Tôi nghi ngờ rằng việc bạn sử dụng lời hứa khác có thể gây ra lỗi này.

App.Person.find đã trả lại lời hứa.Bạn nên sử dụng chính lời hứa đó khi trở về từ model(). Ngoài ra để giải quyết lời hứa đó, bạn chỉ cần trả lại kết quả.

Kiểu triển khai cho Promises mà bạn đã sử dụng thường là cần thiết khi bạn tích hợp một số api không đồng bộ bên ngoài không hỗ trợ Promises.

tôi sẽ cấu trúc lại model() của bạn như vậy. Điều đó có thể khắc phục vấn đề thời gian không đồng bộ của bạn.

App.PersonRoute = Ember.Route.extend({ 
    model: function(params) { 
    var name = "Erik"; 
    var promise = App.Person.find(); 

    promise.then(function() { 
     console.log('Found ' + App.people.get('length')); 
     return App.people.findProperty('name', name) 
    }); 

    return promise; 
    } 
}); 

Tôi đã tìm thấy tài liệu trên Q library rất hữu ích khi tìm ra cách tốt nhất để sử dụng lời hứa. Ember sử dụng RSVP, một thư viện khác nhưng các nguyên tắc thì tương tự nhau.