2016-08-12 1 views
0

Knockout.js를 사용하여 웹 사이트를 개발하고 있지만 제 질문은 일반적인 방식이므로 초점을 맞추지 마십시오."간접"자체 참조를 변경하거나 리디렉션 할 수있는 방법이 있습니까?

나는과 같이,이 경우 viewModel에, 그 변수 이름 자체 내에서 객체를 참조 :이 하위 개체 및 기타에 관해서

var viewModel = { 
    propA: "propA", 
    fnA: function() { 
     alert("I am " + viewModel.propA); //the same as this.propA 
    } 
}; 

그런 식으로, 나는 어떤 문제로 실행되지 않습니다 "멋진"물건.

지금, 나는 나의 뷰 모델에 다른 객체를 병합해야,하지만 난 참조 문제로 실행 :

g_test = {}; //The way with this global variable is just for demonstration purposes 

(function() { 
    var viewModel = { 
     propA: "propA", 
     fnA: function() { 
      alert("I am " + viewModel.propB); 
     } 
    }; 
    g_test.vmA = viewModel; 
})(); 

(function() { 
    var viewModel = { 
     propB: "propB", 
     fnB: function() { 
      alert("I am " + viewModel.propA); 
     } 
    } 

    /** merge viewModel "A" into viewModel "B" */ 
    var vmA = g_test.vmA; 
    for (var key in vmA) { 
     if (vmA.hasOwnProperty(key)) { 
      viewModel[key] = vmA[key]; 
     } 
    } 

    viewModel.fnA(); //I am undefined 
    viewModel.fnB(); //I am propA 
})(); 

당신이 볼 수 있듯이이 fnBpropA을 알고 있지만 fnApropB를 알 수 없습니다.

viewModel 개체에 대한 참조로 this을 사용하면 작업이 수행됩니다. 그러나 나는 모든 객체를 돌보지 않고 모든 viewModelthis으로 대체하거나 필요한 경우 각각의 "도우미 변수"를 소개합니다. 이는 나이가 들기 때문에 필요합니다. 게다가, 내 눈에는 양방향 지식이없는 두 객체를 병합하는 것이 불가능하다는 것을 의미합니다.

viewModel 변수에서 fnA의 변수가 viewModel "B"를 알지 않고도 viewModel "B"를 가리키는 지 감각적 인 방법이 있습니까?

+1

자바 스크립트는 어휘 범위를 가지고있다. 'fnA'에서'viewModel'을 변경하는 유일한 방법은 새로운 값을 할당하는 것입니다. 그러나 그것은'viewModel'이 IIFE에 국한되기 때문에 당신의 예제에서는 불가능합니다. –

+0

'viewModel.propB'를'this.propB'로 대체하면 작동합니다. – Jag

+0

'this'가 대답입니다. 그것이 그곳에있는 이유. –

답변

0

여러 개의 viewModel을 만든 다음 병합을 시도하는 것은 문제가있는 방식 인 것 같아서 어떤 것을 구현하려고하는지 잘 모릅니다. 아마도 더 좋은 방법이있을 것입니다 (적어도 this을 사용하면 mixins을 만드는 것이 올바른 선택이었을 것입니다). 그러나 좋은 이유가 있다고 가정하거나 지금 재 작업을하기에는 너무 많은 노력이 있다고 가정하면 문제를 살펴 보겠습니다.

두 개의 viewModel이 있고이를 서로 병합하여 다른 멤버의 멤버를 알 수 있습니다. 한 방향으로 병합하면 B는 A에 대해 알고 있지만 A는 B에 대해 알지 못합니다. 다른 방향으로 병합해야합니다. Object.assign은 루프의 기능을 수행하는 편리한 방법이지만, 사전 Object.assign 브라우저를 사용하는 경우 viewModel을 통과하는 다른 루프를 추가하여 해당 속성을 vmA에 복사 할 수 있습니다.

결과적으로 메소드가 서로를 참조하는 두 개의 viewModel을가집니다. 각각 propA, propB, fnAfnB이 있지만 fnA (두 개체 모두)은 개체 A의 멤버를 나타내며 그 반대의 경우도 마찬가지입니다.

g_test = {}; //The way with this global variable is just for demonstration purposes 
 

 
function mergeObjects(obj1, obj2) { 
 
    Object.assign(obj1, obj2); 
 
    Object.assign(obj2, obj1); 
 
} 
 

 
(function() { 
 
    var viewModel = { 
 
    propA: "propA", 
 
    fnA: function() { 
 
     alert("fnA: I am " + viewModel.propB); 
 
    } 
 
    }; 
 
    g_test.vmA = viewModel; 
 
})(); 
 

 
(function() { 
 
    var viewModel = { 
 
    propB: "propB", 
 
    fnB: function() { 
 
     alert("fnB: I am " + viewModel.propA); 
 
    } 
 
    } 
 

 
    mergeObjects(g_test.vmA, viewModel); 
 

 
    // to demonstrate which value is outputted by which function 
 
    g_test.vmA.propA = "A.propA"; // not used 
 
    g_test.vmA.propB = "A.propB"; // used by fnA 
 
    viewModel.propA = "B.propA"; // used by fnB 
 
    viewModel.propB = "B.propB"; // not used 
 

 
    viewModel.fnA(); //I am A.propB 
 
    viewModel.fnB(); //I am B.propA 
 
    // also 
 
    g_test.vmA.fnA(); 
 
    g_test.vmA.fnB(); 
 
})();