2013-02-20 11 views
14

tôi có mô hình sau:Làm thế nào để loại trừ thuộc tính nhất định từ Knockoutjs toJS()

var model = { 
    A: 'One', 
    B: 'Two', 
    C: 'Three' 
}; 

tôi ràng buộc các yếu tố giao diện người dùng khác nhau để các trường này, trong đó hoạt động tuyệt vời. Tuy nhiên, tôi chuyển đổi mô hình trở lại với một đối tượng JavaScript để tôi có thể lưu bất kỳ thay đổi đối với máy chủ:

var goingToServer = ko.toJS(model); 

goingToServer sẽ bao gồm các thuộc tính A, B và C. Tuy nhiên, giả sử bất động sản C là một lượng lớn dữ liệu điều đó sẽ không bao giờ thay đổi. Tôi muốn tránh việc gửi lại cho máy chủ.

Có cách nào để tạo toJS()chỉ bao gồm một nhóm trường được xác định trước khi chuyển đổi mô hình trở lại đối tượng JavaScript?

Một điều tôi đã điều tra là Knockout Mapping plugin. Nó có một thiết lập gọi là bao gồm được ghi nhận như vậy:

Khi chuyển đổi mô hình quan điểm của bạn trở lại cho một đối tượng JS, theo mặc định các plugin lập bản đồ sẽ chỉ bao gồm tài sản mà là một phần của mô hình chế độ xem gốc , ngoại trừ nó cũng sẽ bao gồm các tài sản Knockout tạo ra ngay cả khi nó không phải là một phần của đối tượng ban đầu của bạn . Tuy nhiên, bạn có thể chọn để tùy chỉnh mảng này:

Tuy nhiên, dường plugin này không hoạt động như tài liệu, như ko.mapping.toJS() vẫn sẽ bao gồm A, B và C, ngay cả khi tôi vượt qua trong một mảng include của ['A', 'B'] . Tôi đoán tính năng này được dự định bao gồm các trường bổ sung không có trong mô hình ban đầu. Có cách nào để loại trừ các thuộc tính nhất định khi chuyển đổi mô hình trở lại đối tượng JavaScript, không thực hiện điều gì đó hacky chẳng hạn như tạo đối tượng và xóa thuộc tính mà tôi không muốn trước khi gửi tới máy chủ không? Không.

Trả lời

23

Bạn đã thử từ khóa ignore? Nó có cách sử dụng tương tự để bao gồm:

var mapping = { 
    'ignore': ["propertyToIgnore", "alsoIgnoreThis"] 
} 
var viewModel = ko.mapping.toJS(data, mapping); 

Bạn có thể chỉ cần bỏ qua khi bạn thực hiện ánh xạ gốc dữ liệu máy chủ, khi đó nó sẽ không hoàn toàn đối tượng khi bạn chuyển nó về JS .

+0

Điều đó không làm việc, như sau đó bạn không thể liên kết với nó chút nào. –

+0

Bạn đã thử chưa? Vì tài liệu không đề cập đến việc bỏ qua có thể được sử dụng khi quay lại các đối tượng JS hay không. –

+0

Vâng, tôi đã thử nó. Khi tôi 'bỏ qua' trường 'Ghi chú' và khi tôi gọi hàm applyBindings, tôi ngay lập tức nhận được ngoại lệ là trường' Ghi chú' không được tìm thấy trong mô hình. –

2

Ok, tôi đã tìm ra một giải pháp hoạt động mặc dù tôi hy vọng có cách tiếp cận tốt hơn. Bí quyết là để bỏ qua các trường này trong plugin ánh xạ, sau đó thêm chúng theo cách thủ công dưới dạng trường được tính toán. Các trường được tính toán sẽ không bao giờ kết thúc trong đối tượng JavaScript được tạo khi được gọi là toJS.

// Utility function to quickly generate a computed field 
ko.readonly = function (value) 
{ 
    return ko.computed(function() 
    { 
     return value; 
    }); 
}; 

// View Model 
var ViewModel = function (project) 
{ 
    var readonly = ['B', 'C', 'D']; // Fields I want to ignore 
    var mapping = { 
     'ignore': readonly //Read-only properties, we'll add these manually as computed fields 
    }; 

    // Use Mapping plugin to make everything observable, except the fields above 
    ko.mapping.fromJS(project, mapping, this); 

    // Now loop through the read only array and add these fields in as computed 
    for(var i = 0; i < readonly.length; i++) 
    { 
     var field = readonly[i]; 
     this[field] = ko.readonly(project[field]); 
    } 
} 

bây giờ tôi có thể liên kết với các mô hình điểm như bình thường:

ko.applyBindings(new ViewModel(data)); 
3

Nếu chúng ta có một trường hợp mô hình đối tượng phức tạp dưới vm.Thanh toán tham khảo quan sát được như:

{ 
 
    "Summary": { 
 
     "Count": 12, 
 
     "PaymentAmount": 1500, 
 
     "PaymentMethod": "Cheque", 
 
     "PaymentDate": "2015-04-08T22:38:48.552Z", 
 
     "AgentOid": 1208795, 
 
     "AgentName": "Asere Ware" 
 
    } 
 
    //[...] 
 
}

và cần phải bỏ qua chỉ có một số tính chất bên trong, sau đó:

var mapping = { 
 
    'ignore': ['Summary.PaymentMethod', 'Summary.PaymentDate'] //avoid lost some initialized values. 
 
}; 
 
// map updating existing observable (Payment) under my ViewMode (vm) with source "data" JSON object. 
 
ko.mapping.fromJS(data, mapping, vm.Payment);

và đây là kết quả cho vm. Nội dung thanh toán, trong đó chỉ PaymentMethod và PaymentDate là keept:

{ 
 
    "Summary": { 
 
     "Count": 0, 
 
     "PaymentAmount": 0, 
 
     "PaymentMethod": "Cheque", 
 
     "PaymentDate": "2015-04-08T22:38:48.552Z", 
 
     "AgentOid": undefined, 
 
     "AgentName": undefined 
 
    } 
 
    //[...] 
 
}