在 requirejs 加载的 knockout.js 组件中丢失视图模型上下文
Losing view model context in a knockout.js component loaded by requirejs
require js加载的knockout js组件有一个奇怪的问题。
组件很简单。
define([
'jquery',
'knockout'
], function ($, ko) {
function ViewModel(params) {
var self = this;
this.test = 'test';
}
ViewModel.prototype.fetchData = function() {
var self = this;
console.log(this.test);
};
ViewModel.prototype.init = function() {
console.log(this.test);
this.fetchData();
};
ko.components.register('my-component', {
viewModel: ViewModel,
template: '<span data-bind="template: { afterRender: init }"></span>'
});
});
现在,模板绑定可以调用视图模型init方法,但是这个方法本身不能访问fetchData 方法,因为在方法内部 this 绑定到 Window 对象而不是视图模型。
我准备了一个fiddle来显示错误情况:http://jsfiddle.net/ask4artur/3f6jsa4m/47/
我相信 knockout 不会自动调用$data
的this-context 中的afterRender
方法。您可以使用 bind
将 $data
设置为 this
,如下所示:
data-bind="template: { afterRender: init.bind($data) }
var i = 0;
var ViewModel = function() {
this.nr = "Instance " + i++;
}
ViewModel.prototype.logNr = function() {
console.log(this.nr);
};
ko.components.register('test', {
viewModel: ViewModel,
template: '<div data-bind="template: { name: \'testTemplate\', afterRender: logNr.bind($data) }"></div>'
});
ko.applyBindings();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="component: {name: 'test'}"></div>
<div data-bind="component: {name: 'test'}"></div>
<div data-bind="component: {name: 'test'}"></div>
<div data-bind="component: {name: 'test'}"></div>
<div data-bind="component: {name: 'test'}"></div>
<script type="text/html" id="testTemplate">
<div data-bind="text: nr, click: logNr"></div>
</script>
require js加载的knockout js组件有一个奇怪的问题。 组件很简单。
define([
'jquery',
'knockout'
], function ($, ko) {
function ViewModel(params) {
var self = this;
this.test = 'test';
}
ViewModel.prototype.fetchData = function() {
var self = this;
console.log(this.test);
};
ViewModel.prototype.init = function() {
console.log(this.test);
this.fetchData();
};
ko.components.register('my-component', {
viewModel: ViewModel,
template: '<span data-bind="template: { afterRender: init }"></span>'
});
});
现在,模板绑定可以调用视图模型init方法,但是这个方法本身不能访问fetchData 方法,因为在方法内部 this 绑定到 Window 对象而不是视图模型。
我准备了一个fiddle来显示错误情况:http://jsfiddle.net/ask4artur/3f6jsa4m/47/
我相信 knockout 不会自动调用$data
的this-context 中的afterRender
方法。您可以使用 bind
将 $data
设置为 this
,如下所示:
data-bind="template: { afterRender: init.bind($data) }
var i = 0;
var ViewModel = function() {
this.nr = "Instance " + i++;
}
ViewModel.prototype.logNr = function() {
console.log(this.nr);
};
ko.components.register('test', {
viewModel: ViewModel,
template: '<div data-bind="template: { name: \'testTemplate\', afterRender: logNr.bind($data) }"></div>'
});
ko.applyBindings();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="component: {name: 'test'}"></div>
<div data-bind="component: {name: 'test'}"></div>
<div data-bind="component: {name: 'test'}"></div>
<div data-bind="component: {name: 'test'}"></div>
<div data-bind="component: {name: 'test'}"></div>
<script type="text/html" id="testTemplate">
<div data-bind="text: nr, click: logNr"></div>
</script>