如果单击绑定的html列表项,如何获取对根视图模型的引用?
我有一个ViewModel闭包“class”,它使用KnockoutJS进行绑定。
ViewModel保存一个ko.observableArray
,表示无序列表中的每个列表项。
// ViewModel Base
var ViewModel=( function(){
// ctor
function ViewModel(data,id){
// Publics
this.list=ko.observableArray([{name:'one'},{name:'two'},{name:'three'}]);
this.selectedItem=ko.observable(null);
};
// set "selectedItem" when user clicks an <li>
ViewModel.prototype.selectItem=function(){
// below works when using instantiated "vm1"
vm1.selectedItem(this);
// correctly reports the name property of the clicked list item
console.log(vm1.selectedItem().name);
};
// Return Publics
return(ViewModel);
})();
// Build a new view model
var vm1=new ViewModel();
// apply bindings
ko.applyBindings(vm1);
observableArray绑定到Html无序列表。
单击列表项时,每个html列表项在ViewModel中触发.selectItem
。
<ul data-bind='foreach:list'>
<li class='item' data-bind='click: $root.selectItem' >
<span data-bind='text:name'></span>
</li>
</ul>
问题是......
在.selectItem
中,我需要在视图模型实例上设置selectedItem
属性。
但我没有办法从KnockoutJS提供给this
的{{1}}获取视图模型实例。
直接使用selectedItem
实例,但我不希望我的通用ViewModel使用对vm1
vm1
段:
// set "selectedItem" when user clicks an <li>
ViewModel.prototype.selectItem=function(){
// below fails when using "ViewModel" (and numerous other tries by me)
ViewModel.selectedItem(this); // error
console.log(vm1.selectedItem().name);
};
function log(){console.log.apply(console,arguments);}
// ViewModel Base
var ViewModel=( function(){
// ctor
function ViewModel(data,id){
// Publics
this.list=ko.observableArray([{name:'one'},{name:'two'},{name:'three'}]);
this.selectedItem=ko.observable(null);
};
// set "selectedItem" when user clicks an <li>
ViewModel.prototype.selectItem=function(){
// below works when using specified vm1
// below fails when using ViewModel.selectedItem(this)
vm1.selectedItem(this);
alert('Clicked on: '+vm1.selectedItem().name);
};
// Return Publics
return(ViewModel);
})();
// Build a new view model
var vm1=new ViewModel();
// apply bindings
ko.applyBindings(vm1);
答案 0 :(得分:3)
The recommended way of writing methods in your viewmodels是在构造函数中定义它们,而不是在原型中定义它们,因此它们对构造的视图模型进行操作:
function ViewModel(data,id){
var that = this;
// Publics
this.list = ko.observableArray([{name:'one'},{name:'two'},{name:'three'}]);
this.selectedItem = ko.observable(null);
this.selectItem = function(item){
that.selectedItem(item);
alert('Clicked on: '+that.selectedItem().name);
};
}
此外,您应该使用$parent
上下文,而不是$root
,因此它甚至可以在另一个视图模型中使用:
<ul data-bind='foreach:list'>
<li class='item' data-bind='click: $parent.selectItem'>
<span data-bind='text:name'></span>
</li>
</ul>
答案 1 :(得分:0)
我通过这种方式获得视图模型参考,而无需在视图模型中对视图模型实例进行硬编码&#34; class&#34;。
它涉及抓取浏览器的事件对象并使用它来获取ViewModel SELECT p.username, pcm.status
FROM Profile p LEFT JOIN p.mappings pcm
WHERE pcm.club.id = 480
到$root
。
虽然这有效,但我认为必须有一种更简单的方法来消除通用ViewModel中的硬编码引用。
还有其他想法吗?
ko.contextFor(event.target).$root
// set "selectedItem" when user clicks an <li>
ViewModel.prototype.selectItem=function(item,event){
// get a reference to the view model using ko.contextFor
var theVM=ko.contextFor(event.target).$root;
// set the "selectedItem" property on the view model
theVM.selectedItem(this);
// working!
alert(vm1.selectedItem().name);
};
&#13;
// ViewModel Base
var ViewModel=( function(){
// ctor
function ViewModel(data,id){
// Publics
this.list=ko.observableArray([{name:'one'},{name:'two'},{name:'three'}]);
this.selectedItem=ko.observable(null);
};
// set "selectedItem" when user clicks an <li>
ViewModel.prototype.selectItem=function(item,event){
var theVM=ko.contextFor(event.target).$root;
theVM.selectedItem(this);
// It works!
alert(vm1.selectedItem().name);
};
// Return Publics
return(ViewModel);
})();
// Build a new view model
var vm1=new ViewModel();
// apply bindings
ko.applyBindings(vm1);
&#13;