2012-02-10 29 views
6

Tôi hiện đang gặp sự cố khi làm mới giao diện người dùng khi tôi nhận dữ liệu mới từ máy chủ cho một mục duy nhất trong một đối tượng có thể quan sát được của đối tượng bao bọc. .Không thể cập nhật giao diện người dùng Knockout với đối tượng dữ liệu mới

xem xét như sau:

var vm = { 
.... 
localEdited: ko.mapping.fromJS(new ItemWrapper(defaultModelSerialised)), 
selected: ko.observable(null), 
editItem: function(data) { 
    // clone a temporary copy of data for the dialog when opening (*.localEdited on dialog) 
    var clonedData = ko.toJS(data); 
    ko.mapping.fromJS(clonedData, null, this.localEdited); 

    // selected should now point to the item in the obserable array which will be refreshed 
    this.selected(data); 

    // open dialog... 
}, 
submitDialog: function(data) { 

    // submit data to server... 

    // (1) commit the data back to UI (new item is return in resp.entity from server) 
    vm.selected(new ItemWrapper(resp.entity)); 

    // at this point the UI isn't showing the updated value 

    // (2) however if I do this it reflects the data change in the UI 
    this.selected().Name("changed"); // updates the UI. 
} 

Ai đó có thể giải thích tại sao đi qua trong ItemWrapper vào vm.selected không cập nhật giao diện người dùng trong khi ở (2) nó hoạt động. Tôi không muốn phải thiết lập mỗi tài sản như trong (2) cho mỗi tài sản.

ItemWrapper trông giống như vậy:

function PoolWrapper(pool) { 
    this.Name = ko.observable(pool.Name); 

    // more properties... 
} 
+0

Bạn có ràng buộc mọi thứ với vm.selected trong html không? Nếu không, tại sao bạn mong đợi knockout để cập nhật giao diện người dùng trong dòng này vm.selected (new ItemWrapper (resp.entity)); ? –

+0

Có lẽ bạn có thể nhận được một cái gì đó trong jsFiddle để chứng minh? Sẽ dễ dàng hơn khi nhìn thấy một phần mã của bạn. Tôi giả định rằng có lẽ bạn đang làm 'với: selected' trong giao diện người dùng của bạn hoặc sử dụng một mẫu chống lại' lựa chọn'? –

+0

@RomanBataev: Không có gì bị ràng buộc với vm.selected trực tiếp. Trong editItem() dữ liệu được truyền vào là từ ItemWrapper trong observableArray. Biến được chọn sau đó trỏ đến mục trong mảng. Như điểm (2) chứng minh nó được ràng buộc với giao diện người dùng ok khi đi qua các thuộc tính riêng lẻ, nhưng không phải khi chuyển ItemWrapper vào biến đã chọn(). – jaffa

Trả lời

6

OK- vấn đề là máy nhái của bạn kết thúc với bản đồ siêu dữ liệu trên chúng và cuối cùng điều này gây ra đệ quy khi cố gắng gọi ko.mapping.fromJS.

Giải pháp là tạo các bản sao của bạn bằng cách sử dụng ko.mapping.toJS thay vì ko.toJS, để bạn có được bản sao sạch (không có siêu dữ liệu ánh xạ).

Dưới đây là một fiddle Cập nhật: http://jsfiddle.net/rniemeyer/tDDBp/

+0

Cảm ơn vì điều này. Không chắc tại sao ko.toJS sẽ giữ dữ liệu bản đồ và ko.mapping.toJS thì không. – jaffa

+0

ko.mapping.toJS đặc biệt biết về các tùy chọn ánh xạ và loại bỏ chúng, trong khi ko.toJS không có ý tưởng về plugin ánh xạ. –

0

Cái gì tôi cũng stumbled khi ngày hôm nay rằng tôi nghĩ rằng tôi muốn chia sẻ:

Nếu bạn Clone sử dụng:

var clone = ko.mapping.fromJS(ko.mapping.toJS(itemToClone)); 

Sau đó clone sẽ tước bỏ bất kỳ quan sát được tính toán nào. Chúng sẽ tồn tại như là giá trị cuối cùng của hàm, nhưng không còn hoạt động như một hàm quan sát được tính toán nữa.

Nếu hàng của bạn là một mô hình phức tạp với quan sát tính mà bạn muốn giữ trên bản sao của bạn, bạn có thể làm như sau:

var clone = ko.mapping.fromJS(ko.mapping.toJS(itemToClone), null, new itemModel()); 

đâu itemModel là mô hình phức tạp của bạn cho mặt hàng của bạn có chứa quan sát tính của bạn.

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