2012-05-10 3 views
11

Knockout에서 Observable 객체를 복제하여 일종의 트랜잭션 메커니즘을 만드는 가장 좋은 방법은 무엇입니까? 예를 들어

이 모델을 편집 :
관찰 가능 항목을 복제하는 가장 좋은 방법은 무엇입니까?

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); 
}; 

나는 사용자가 편집하기 전에 그 객체의 상태를 저장합니다. 그리고 사용자가 편집을 취소 할 경우 - 롤백 개체 상태. 단지 같은 다른 프로젝트를 생성한다

간단한 방법 :

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

하지만 그것은 우아한 해결책이 있는지 모르겠어요 ..

그래서, 어떤 아이디어? 내가 그 모방 jQuery의 $.extend 기능을하는 기능을 가지고

첫째 :

답변

15

나는 일반적으로 다음과 같은 것을 할. source 개체의 observable (또는 관찰 할 수없는) 속성 값이 모두있는 target 개체를 채 웁니다.

// 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; 
}; 

은 그 때 나는 기본적으로 개체가 JSON에 복사로 변환 한 후 JSON 사본을 받아 새로운 자바 스크립트 객체를 빌드 copy 기능을 가지고있다. 이렇게하면 모든 메모리 포인터가 복사되지 않고 원래의 개체와 일치하는 새로운 개체를 가질 수 있습니다.

var tempAction = ko.utils.clone(action, new Action()); 
: 여기에 하나의 키는

// 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); 
}; 

당신은 다음과 같이 사용할 수 있습니다 (그렇지 않으면 우리가 채울 어떤 속성 아무 생각이 없을 것) 새 객체의 빈 인스턴스를 전달해야 할 것입니다

+0

ko.mapping 플러그인을 사용하여 원본 소스 개체에서 새 대상 개체로 매핑 할 수 없습니까? – jaffa

+0

@jaffa - 예, 매핑 플러그인이 적합한 옵션입니다. 그러나 사소한 필요성 때문에 잔인 할 수 있습니다. 또한 매핑 확장 프로그램이 필요하지 않은 상황에서 매우 유용한 'extendObservable' 함수를 발견했습니다. – ericb

+0

ko.computed 값과 어떻게 작동합니까? 나는 toJSON과 JSON.parse를 사용하여 객체를 복사하면 모든 계산 된 값이 손실 될 것이라고 생각합니다. –

관련 문제