.computed () Observable 내부에서 녹아웃의 $ parent / $ root 유사 변수를 어떻게 사용할 수 있습니까?
A는 내부 knockout.js 표현을 결합, 내가 사용할 수 있습니다 $data
, $parent
그리고 $root
pseudovariables을 . JavaScript에서 선언 된 ko.computed
Observable을 사용할 때 해당 유사 변수를 어떻게 얻을 수 있습니까?
자식 컬렉션이있는 부모 뷰 모델이 있고 부모 뷰 모델에는 selectedChild
관찰 가능 항목이 있습니다. 따라서 데이터 바인딩 표현식을 사용하여 현재 선택된 자식에 CSS 클래스를 추가 할 수 있습니다.
<ul data-bind="foreach: children">
<li data-bind="text: name,
css: {selected: $data === $root.selectedChild()},
click: $root.selectChild"></li>
</ul>
<script>
vm = {
selectedChild: ko.observable(),
children: [{name: 'Bob'}, {name: 'Ned'}],
selectChild: function(child) { vm.selectedChild(child); }
};
ko.applyBindings(vm);
</script>
하지만 내 뷰 모델은 더 복잡해질 것이며 "내가 선택 했습니까?" 단일 요소에 단일 CSS 클래스를 추가하는 것 이상을 수행 할 수 있습니다. isSelected
자식 뷰 모델에 대해 계산 된 속성 을 만들고 싶으 므로 이에 종속 된 다른 계산 된 속성을 추가 할 수 있습니다.
난 그냥을 의미 자바 스크립트를 작성 해봤 $data
및 $root
내 호출 할 때 녹아웃 그 변수를 정의하고 어떻게 든 그들을 범위에있을 가질 수있는 오프 기회에, computed
평가자 기능 :
{
name: 'Bob',
isSelected: ko.computed(function(){ return $data === $root.selectedChild(); })
}
그러나 그런 행운 : 내 평가자 안에 function
모두 $data
와 $root
없습니다 undefined
.
또한 ko.contextFor
내 평가자 내부에서 $data
및에 대한 액세스 권한을 부여하기 때문에 사용해 보았습니다 $root
. 불행히도 내 평가자 함수 내에서도 contextFor
항상 undefined
. (어쨌든 나는이 전략에 대한 높은 희망을 내놓지 않았다. 만약 내가 이런 식으로 뒤로 가야한다면 녹아웃이 의존성을 얼마나 잘 추적 할 수 있을지는 분명하지 않다.)
항상 부모 뷰 모델을 다시 참조하는 각 하위 뷰 모델에 속성을 수동으로 설정할 수 있습니다. 그러나 나는 녹아웃이 나를 위해 이것을 할 수있는 능력을 가지고 있다는 것을 알고 있으며, 적어도 내가 직접 쓰기 전에 그 메커니즘을 사용할 수 있는지 여부를 조사하고 싶습니다.
위의 바인딩 표현식을 계산 된 Observable로 변환하는 것이 가능해야 할 것 같습니다. 결국 녹아웃이 이미하는 일입니다 .
다른 깔끔한 트릭은 선언적 바인딩이 단순히 계산 된 관찰 가능 항목으로 구현된다는 것입니다.
하지만 내 자신의 계산 된 Observable을 작성할 때 $data
및 $root
pseudovariable을 어떻게 처리해야 합니까?
유사 변수는 데이터 바인딩 컨텍스트에서만 사용할 수 있습니다. 보기 모델 자체는 이상적으로이를 표시하는보기에 대해 알거나 종속성을 가져서는 안됩니다.
따라서 뷰 모델에 계산 된 옵저버 블을 추가 할 때 바인딩 방법에 대한 지식이 없습니다 (예 : $ root가 될 것). 보기 모델 또는보기 모델의 일부는 다른 수준에서 페이지의 여러 영역에 개별적으로 바인딩 될 수도 있으므로 시작하는 요소에 따라 의사 변수가 달라집니다.
수행하려는 작업에 따라 다르지만 isSelected
이 항목이 상위 뷰 모델에서 선택한 항목과 동일한 지 여부를 나타내는 계산 된 관찰 가능 항목을 자녀가 갖도록하려면 다음을 수행 할 방법을 찾아야합니다. 부모는 자녀에게 제공됩니다.
한 가지 옵션은 부모를 자녀의 생성자 함수에 전달하는 것입니다. 부모에 대한 포인터를 자식의 속성으로 추가 할 필요도 없으며 계산 된 Observable에서 직접 사용할 수 있습니다.
다음과 같은 것 :
var Item = function(name, parent) {
this.name = ko.observable(name);
this.isSelected = ko.computed(function() {
return this === parent.selectedItem();
}, this);
};
var ViewModel = function() {
this.selectedItem = ko.observable();
this.items = ko.observableArray([
new Item("one", this),
new Item("two", this),
new Item("three", this)
]);
};
여기 샘플 : http://jsfiddle.net/rniemeyer/BuH7N/
선택한 상태 만 신경 쓰는 경우 http://jsfiddle.net/rniemeyer/R5MtC/selectedItem
와 같이 하위 생성자에 Observable에 대한 참조를 전달하도록 조정할 수 있습니다 .
If your parent view model is stored in a global variable, then you could consider not passing it to the child and using it directly like: http://jsfiddle.net/rniemeyer/3drUL/. I prefer to pass the reference to the child though.
In my experience the approach in @RP Niemeyer's answer is fine if Item
s live for the duration of the application. But if not, it can lead to memory leaks, because Item
's computed observable sets up a reverse dependency from the ViewModel
. Again, that's ok if you never get rid of any Item
objects. But if you do try to get rid of Item
s they won't get garbage collected because knockout will still have that reverse dependency reference.
You could make sure to dispose() of the computed, maybe in a cleanup() method on Item
that gets called when the item goes away, but you have to remember to do that whenever removing Item
s.
Instead, why not make Item
a little less smart and have ViewModel
tell it when it is selected? Just make Item
's isSelected()
a regular old observable and then in ViewModel
subscribe to selectedItem
and update inside that subscription.
Or, use @RP Niemeyer's pub/sub solution. (To be fair, this solution came about after his answer here.) You'll still need to clean up, though, because it creates reverse dependencies, too. But at least there's less coupling.
See the answer to my recent question on this same topic for more details.
Use $context
instead of $parent
when within a foreach binding.
'program tip' 카테고리의 다른 글
SaveOrUpdate 대 업데이트 및 NHibernate에서 저장 (0) | 2020.12.09 |
---|---|
html에서 프레임이 사용되지 않는 이유는 무엇입니까? (0) | 2020.12.09 |
URL 매개 변수와 쿼리 문자열의 차이점은 무엇입니까? (0) | 2020.12.09 |
for 루프에서 임의의 대상 표현식이 허용되는 이유는 무엇입니까? (0) | 2020.12.09 |
메모리 누수입니까? (0) | 2020.12.09 |