2012-05-10 28 views
11

Cách tốt nhất để sao chép các đối tượng quan sát được trong Knockout để tạo ra loại cơ chế giao dịch là gì?

Ví dụ chỉnh sửa mô hình này:
Cách tốt nhất để nhân bản các quan sát?

var Action = function (name, ownerType, condition, expression, args) { 
    var self = this; 
    this.name = ko.observable(name); 
    this.ownerType = ko.observable(ownerType); 
    this.condition = ko.observable(condition); 
    this.expression = ko.observable(expression); 
    this.args = ko.observable(args); 
}; 

Tôi muốn lưu trạng thái của đối tượng đó trước khi sử dụng sẽ chỉnh sửa nó. Và nếu người dùng sẽ hủy chỉnh sửa - trạng thái đối tượng cuộn ngược.

đơn giản nhất cách chỉ là tạo ra một dự án như:

self.tempAction = new Action(action.name(), action.ownerType(), action.condition(), action.expression(), action.args()); 

Nhưng tôi không chắc chắn rằng đó là giải pháp thanh lịch ..

Vì vậy, bất kỳ ý tưởng?

Trả lời

15

Tôi thường làm điều gì đó như sau:

Trước tiên tôi có một chức năng bắt chước $.extend chức năng của jQuery. Nó điền một đối tượng target với tất cả các giá trị thuộc tính observable (hoặc không thể quan sát) của đối tượng source.

// extends observable objects intelligently 
ko.utils.extendObservable = function (target, source) { 
    var prop, srcVal, isObservable = false; 

    for (prop in source) { 

     if (!source.hasOwnProperty(prop)) { 
      continue; 
     } 

     if (ko.isWriteableObservable(source[prop])) { 
      isObservable = true; 
      srcVal = source[prop](); 
     } else if (typeof (source[prop]) !== 'function') { 
      srcVal = source[prop]; 
     } 

     if (ko.isWriteableObservable(target[prop])) { 
      target[prop](srcVal); 
     } else if (target[prop] === null || target[prop] === undefined) { 

      target[prop] = isObservable ? ko.observable(srcVal) : srcVal; 

     } else if (typeof (target[prop]) !== 'function') { 
      target[prop] = srcVal; 
     } 

     isObservable = false; 
    } 
    return target; 
}; 

Sau đó, tôi có một hàm copy rằng về cơ bản chuyển đổi đối tượng được sao chép vào JSON và sau đó mất bản sao JSON và xây dựng một đối tượng javascript mới. Điều này đảm bảo tất cả các con trỏ bộ nhớ không được sao chép và bạn có một đối tượng hoàn toàn mới khớp với đối tượng gốc của bạn. Một trong những mấu chốt ở đây là bạn phải vượt qua trong một thể hiện sản phẩm nào của một đối tượng mới (nếu không chúng tôi sẽ không có ý tưởng những gì thuộc tính để cư)

// then finally the clone function 
ko.utils.clone = function(obj, emptyObj){ 
    var json = ko.toJSON(obj); 
    var js = JSON.parse(json); 

    return ko.utils.extendObservable(emptyObj, js); 
}; 

Sau đó bạn có thể sử dụng nó như vậy:

var tempAction = ko.utils.clone(action, new Action()); 
+0

Bạn có thể không chỉ sử dụng plugin ko.mapping để ánh xạ từ đối tượng nguồn gốc đến đối tượng đích mới không? – jaffa

+0

@jaffa - vâng, plugin ánh xạ sẽ là một tùy chọn phù hợp. Tuy nhiên nó có thể là quá mức cần thiết cho các nhu cầu tầm thường. Ngoài ra, tôi đã tìm thấy hàm 'extendObservable' khá hữu ích trong các tình huống mà plugin bản đồ không cần ứng dụng rộng. – ericb

+0

Cách này hoạt động với các giá trị ko.computed? Tôi sẽ nghĩ rằng bằng cách sử dụng toJSON và JSON.parse để sao chép một đối tượng sẽ mất tất cả các giá trị tính toán của nó. –

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