我有以下代码:
function ViewModel() {
var self = this;
self.newCategory = {
name: ko.observable(''),
canSubmit: function() {
return this.name() !== '';
},
submit: function() {
var data = 'name=' + this.name();
$.post('/api/createcategory', data, function(res) {
//...
});
}
};
}
和HTML
<button type="button" data-bind="enable: newCategory.canSubmit(), click: newCategory.submit">Create category</button>
在canSubmit()
函数中,this
指的是self.newCategory
,正如我所期待的那样。但是,由于submit()
函数的某些原因,this
引用ViewModel()
为什么会这样?
答案 0 :(得分:3)
Knockout在它们绑定的viewmodel的上下文中调用函数,在您的情况下是主视图模型。提示:submit
的视图模型不是您分配给newCategory
的对象。
在你的装订中,你会做两件事:
enable: newCategory.canSubmit()
在newCateory
上立即调用该函数。这就是this
将在函数内部的内容。click: newCategory.submit
提及该函数,即knockout创建一个将在当前视图模型的上下文中运行的点击处理程序。请注意,canSubmit
实际上应该是可观察的。
当您更改绑定上下文时,例如使用with
绑定,行为就像您期望的那样。
<!-- ko with: newCategory -->
<button data-bind="enable: canSubmit, click: submit">Create category</button>
<!-- /ko -->
对于子视图模型,我喜欢创建实际的独立构造函数:
function Category() {
var self = this;
self.busy = ko.observable(false);
self.name = ko.observable('');
self.canSubmit = ko.computed(function() {
return !self.busy() && self.name() > '';
});
}
Category.prototype.submit = function() {
var self = this;
if ( !self.canSubmit() ) return;
self.busy(true);
$.post('/api/createcategory', {
name: this.name()
}).done(function(res) {
//...
}).always(function() {
self.busy(false);
});
};
function ViewModel() {
var self = this;
self.newCategory = new Category();
}
和
<!-- ko with: newCategory -->
<input type="text" data-bind="name">
<button data-bind="enable: canSubmit, click: submit">Create category</button>
<img src="spinner.gif" data-bind="visible: busy">
<!-- /ko -->