2012-02-16 6 views
6

Tôi tìm nạp đối tượng json từ máy chủ và điền vào chế độ xem của tôi. Sau đó tôi thay đổi dữ liệu, đẩy nó trở lại máy chủ. Sau đó, tôi lấy một bản sao dữ liệu mới hy vọng nó sẽ làm mới chế độ xem của tôi với bất kỳ thay đổi nào. Tuy nhiên điều đó không xảy ra. TIAKnockout.js ko.mapping.toJS không làm mới dữ liệu trong chế độ xem của tôi

$(document).ready(function() { 
    var customer_id = get_customer_id(); 
    var data = load_model(); 
    contract_model = ko.mapping.fromJS(data,{}); 
    ko.applyBindings(contract_model); 
} 

function load_model(){ 
    var url = '/ar/contract_json?contract_id='+get_contract_id(); 
    var data = ''; 
    $.ajax({ 
     type:'GET', 
     url:url, 
     async:false, 
     success: function(returningValue){ 
      data = returningValue; 
     } 
    }); 
    return data; 
} 

Tải ban đầu này hoạt động tốt. Sau đó tôi làm một số công cụ và thay đổi một trong các quan sát và đẩy dữ liệu đó trở lại máy chủ. Server nhận được bản cập nhật và sau đó tôi thực hiện tìm nạp dữ liệu mới để chế độ xem sẽ làm mới (tôi biết tôi có thể truyền lại dữ liệu mới trong một bước nhưng trong mã này tôi chưa được refactored).

function refresh_data(contract_model){ 
    var url = '/ar/contract_json?contract_id='+get_contract_id(); 
    $.post(url,function(data){ 
     console.log(data); 
     ko.mapping.fromJS(contract_model,{},data); 
     ko.applyBindings(contract_model); 
     console.log(ko.mapping.toJS(contract_model)) 
    }); 

} 

function refresh_data(contract_model){ 
    var url = '/ar/contract_json?contract_id='+get_contract_id(); 
    $.post(url,function(data){ 
     console.log(data); 
     ko.mapping.fromJS(contract_model,{},data); 
     console.log(ko.mapping.toJS(contract_model)) 
    }); 

} 

function push_model(contract_model,refresh){ 
    var url = '/ar/update_contract'; 
    var data = {'contract':ko.mapping.toJSON(contract_model)} 

    delete data['lines']; 
    $.post(url,data,function(return_value){ 
     if (refresh){ 
      refresh_data(contract_model); 
     }; 
    }); 
} 

Tất cả các thông báo trên bàn điều khiển đều hiển thị dữ liệu mới nhưng chế độ xem của tôi không bao giờ cập nhật.

Trả lời

20

Tôi tin rằng vấn đề là với thứ tự tham số bạn chuyển vào hàm ko.mapping.fromJS khi bạn đang cập nhật contract_model.

Bạn có:

ko.mapping.fromJS(contract_model,{},data); 

bạn muốn:

ko.mapping.fromJS(data, {}, contract_model); 
+12

Tài liệu KnockOut cho plugin Ánh xạ là, IMO, sai cú pháp khi gọi ko.mapping.fromJS (...). Các tài liệu hiển thị như sau: ko.mapping.fromJS (dữ liệu, viewModel), nhưng rõ ràng điều này nên là: ko.mapping.fromJS (dữ liệu, {}, viewModel) –

+1

Dành thời gian cho việc này. Cảm ơn bạn đây là một trợ giúp lớn. –

+0

Tôi cũng đã dành hàng giờ cho việc này. Tôi nợ bạn một gói sáu – stackoverfloweth

2

@ câu trả lời seth.miller là đúng. Bạn cũng có thể bỏ qua tham số "tùy chọn" ở giữa nếu contract_model của bạn giống với thông số đã được ánh xạ trước đó. Nếu chỉ có hai đối số, ko.mapping.fromJS sẽ kiểm tra xem đối số thứ hai có thuộc tính "__ko_mapping__" hay không. Nếu vậy, nó xử lý nó như là một mục tiêu, nếu không nó xử lý nó như là một đối tượng tùy chọn.

+0

Ugh điều này là câm. Nếu đối số thứ hai không có thuộc tính '" __ko_mapping __ "' và đối số thứ ba không tồn tại thì nó thực sự sẽ coi đối số thứ hai là đích. –

0

Dựa trên quan sát của @ DBueno - đối với bất kỳ ai sử dụng bản in, tôi khuyên bạn nên nhận xét về sự quá tải cụ thể này từ tệp knockout.mapping.d.ts của bạn.

fromJS(jsObject: any, targetOrOptions: any): any; 

enter image description here

Sau đó bạn sẽ nhận được một lỗi thời gian biên dịch nếu bạn cố gắng làm:

ko.mapping.fromJS(item.data, item.target); 

và bạn có thể thay thế nó với an toàn hơn nhiều

ko.mapping.fromJS(item.data, {}, item.target); 

An toàn hơn vì có hay không item.target đã được ánh xạ trước đó (và do đó sẽ h ave a __ko_mapping__ tài sản) nó sẽ luôn luôn sao chép các thuộc tính.