我正在尝试为我的应用程序创建基本视图模型,但我正在努力访问基本视图模型的上下文。
这是我的基本视图模型:
define(["config", 'services/logger'], function (config, logger) {
'use strict';
var
app = require('durandal/app'),
baseViewModel = function () {
this.items = ko.observableArray();
this.title = ko.observable();
this.selectedItem = ko.observable();
};
baseViewModel.prototype = (function () {
var
populateCollection = function (initialData, model) {
var self = this;
if (_.isEmpty(self.items())) {
ko.utils.arrayForEach(initialData, function (item) {
// self here works for all extending modules such as users
self.items.push(new model(item));
});
}
},
deleteItem = function (item) {
// "this" here same as prototype gives me window object :(
// so removing never happes
this.items.remove(item);
logger.log(config.messages.userMessages.confirmDeleted(item.Name()), {}, '', true);
},
confirmDelete = function (item) {
var
userMessage = config.messages.userMessages.confirmDelete(item.Type(), item.Name()),
negation = config.confirmationModalOptions.negation,
affirmation = config.confirmationModalOptions.affirmation;
app.showMessage(userMessage, 'Deleting ' + item.Type(), [affirmation, negation]).then(
function (dialogResult) {
dialogResult === affirmation ? deleteItem(item) : false;
});
};
return {
populateCollection: populateCollection,
confirmDelete: confirmDelete,
deleteItem: deleteItem
}
})();
return baseViewModel;
});
以及我使用这种非工作事物的例子是:
define(['services/logger', 'models/user', 'viewmodels/baseviewmodel', 'services/dataservice'], function (logger, user, baseviewmodel, dataservice) {
var
users = new baseviewmodel();
users.title('Users')
users.searchTerm = ko.observable().extend({ persist: users.title() + '-searchterm' });
users.activate = function () {
this.populateCollection(dataservice.getUsers, user.model);
}
return users;
});
使用populateCollection
正确填充项目。
confirmDelete
也在模板中正确绑定,这可能是由于不需要上下文
但deleteItem
需要上下文,因此可以访问items
并在其上调用remove
。
如何正确访问
this
作为baseViewModel
的上下文 所以我可以用这种模式轻松地在我的方法中引用它?
非常感谢
答案 0 :(得分:1)
编辑:看起来好像this
未在deleteItem中正确绑定,因为它是在confirmDelete内部的回调中调用的。因此,请在原始模型上尝试此片段
confirmDelete = function (item) {
var self=this,
userMessage = config.messages.userMessages.confirmDelete(item.Type(), item.Name()),
negation = config.confirmationModalOptions.negation,
affirmation = config.confirmationModalOptions.affirmation;
app.showMessage(userMessage, 'Deleting ' + item.Type(), [affirmation, negation]).then(
function (dialogResult) {
dialogResult === affirmation ? self.deleteItem.call(self,item) : false;
});
};
我之前从未使用过'揭示原型模式',所以这里是如何做到这一点而不遵守我们都不理解的模式:)
我将所有内容声明为我的viewmodel的属性并使用var self = this
,这样我的所有代码都非常明确。这是你的baseviewmodel,重写。如果所有viewmodel逻辑都封装在viewmodel中,并且viewmodel在构造函数/函数定义中声明其依赖项,则通常很有帮助。
baseViewModel = function (dataService,userModel) {
var self = this;
self.items = ko.observableArray();
self.title = ko.observable();
self.searchTerm = ko.observable().extend({ persist: self.title() + '-searchterm' });
self.selectedItem = ko.observable();
self.populateCollection = function (initialData, model) {
if (_.isEmpty(self.items())) {
ko.utils.arrayForEach(initialData, function (item) {
// self here works for all extending modules such as users
self.items.push(new model(item));
});
}
};
self.activate = function () {
this.populateCollection(dataservice.getUsers, userModel);
}
self.deleteItem = function (item) {
// "this" here same as prototype gives me window object :(
// so removing never happes
self.items.remove(item);
logger.log(config.messages.userMessages.confirmDeleted(item.Name()), {}, '', true);
};
self.confirmDelete = function (item) {
var
userMessage = config.messages.userMessages.confirmDelete(item.Type(), item.Name()),
negation = config.confirmationModalOptions.negation,
affirmation = config.confirmationModalOptions.affirmation;
app.showMessage(userMessage, 'Deleting ' + item.Type(), [affirmation, negation]).then(
function (dialogResult) {
dialogResult === affirmation ? self.deleteItem(item) : false;
});
};
};
请注意,因为我还将您的依赖项移动到viewmodel构造函数中,现在您的初始化代码如下所示:
define(['services/logger', 'models/user', 'viewmodels/baseviewmodel', 'services/dataservice'], function (logger, user, baseviewmodel, dataservice) {
var users = new baseviewmodel(dataservice,user.model);
users.title('Users')
return users;
});