我花了最后几天研究以下KnockoutJS问题。
我有一个包含3个视图模型的页面。我正在使用带有id的div来指定绑定,即:
ko.applyBindings(new viewModel(datasource), $("#sectionQualifications")[0]);
我也在使用RequireJS,它确实有助于我的应用程序模块化,当然也适用于KnockoutJS。
我的问题涉及在我的页面上有(如上所述)3个视图模型..没有重叠,但每个视图模型都有一个SAVE功能。所以快速浏览一个viewmodel片段:
function viewModel(data) {
self = this;
self.quals = ko.observableArray(data),
self.addQual = function () {
self.quals.push(new qualification());
},
self.remove = function (item) {
// Remove from the database IF we have an actual record in our viewmodel
if (item.Id !== 0) {
dataservice_qualifications.deleteEntity(item.Id, ko.toJSON(item),
{
success: function (ret) {
common.notifyOK('Qualification removed');
},
error: function (err) {
common.notifyError('Cannot remove that qualification');
console.log('Qualification Remove Error', err);
console.log('Remove error object', this.Id);
}
}
);
}
// Remove from the actual view model
self.quals.remove(item);
}
// Save and move on.. we need to iterate through the qualifications, update any existing rows (ID NOT 0) or
// add new entries (ID IS 0)
self.save = function () {
var saveData = ko.toJS(this.quals);
for (var i in saveData) {
// New qualification entry
if (saveData[i].Id === 0) { // New qualification entry
dataservice_qualifications.postEntity(ko.toJSON(saveData[i]),
{
success: function (ret) {
},
error: function (error) {
common.notifyError('Cannot add qualification ' + saveData[i].qualificationName);
console.log('Qualification add error', error);
}
}
);
} // eof NEW qualification
if (saveData[i].Id > 0) {
dataservice_qualifications.putEntity(saveData[i].Id, ko.toJSON(saveData[i]),
{
success: function (ret) {
},
error: function (error) {
common.notifyError('Cannot update qualification ' + saveData[i].qualificationName);
console.log('UPDATED: ERROR:', error);
}
}
);
} // eof UPDATED qualification
} // eof saveData loop
common.notifyOK('Qualifications updated');
} // eof savenext function
return;
};
从上面的示例中,我将有另外两个相似的视图模型,它们具有上述SAVE功能。所以当然我想用jQuery来点击一个按钮并保存所有3个视图模型(即通过每个视图模型的SAVE功能)。
因为我正在使用RequireJS,所以我尝试公开一个“public”函数,该函数依次尝试在内部调用viewModel.save()函数,如下所示:
function saveModel() {
viewModel.save();
}
// PUBLIC INTERFACE
return {
saveModel: saveModel,
loadViewModel: koMapData
}
所以理论上我可以从应该触发视图模型保存的地方调用“saveModel”函数吗?
任何帮助真的很感激。顺便说一句,我已经走上了尝试创建视图模型的道路:
var viewModel = {
save: function() {
blah blah...
}
}
但是,那也没有真正的运气?我确信我遗漏了一些简单的东西,因为我认为你可以/应该能够以某种方式从外部的viewmodel触发一个函数?
修改 仅供参考,模型不要重叠..
提前致谢, 大卫。
答案 0 :(得分:2)
您可以在这样的对象中合并视图模型:
var mainVModel = {
vModel1: { // has save method},
vModel2: { // has save method},
saveAll : function(){
mainVModel.vModel1.save();
mainVModel.vModel2.save();
}
}
ko.applyBindings(new mainVModel());
答案 1 :(得分:0)
实际上感谢@XGreen的建议,我可以看到它运行良好,但是我使用的是requirejs,所以我的应用程序结构不太匹配。
但是,我在以下解决方案中取得了成功:
首先,我以略微不同的方式创建了viewmodel ..
var viewModel = {
quals: ko.observableArray([]),
addQual: function () {
viewModel.quals.push(new qualification());
},
remove: function (item) {
// Do the remove bit..
},
save: function () {
var saveData = ko.toJS(viewModel.quals);
// Do the save stuff..
} // eof savenext function
}; // eof viewModel def
所以定义了viewmodel,然后我有一个辅助函数来访问viewmodel的SAVE函数:
// Private: Allows external access to save the viewmodel
var viewModelFunctions = {
saveModel: function () {
viewModel.save();
}
}
..然后最后,因为我在requirejs结构中使用了揭示模块模式,我创建了一个公共接口函数,如下所示:
function koMapData(incomingData) {
datasource = (incomingData === null) ? [new qualification()] : incomingData;
viewModel.quals = ko.observableArray(ko.toJS(datasource));
ko.applyBindings(viewModel, $("#sectionQualifications")[0]);
}
// PUBLIC INTERFACE
return {
viewModelFunctions: viewModelFunctions,
loadViewModel: koMapData
}
所以你可以看到viewModelFunctions的最后一部分,这意味着在另一个模块(或任何地方)我可以通过以下方式远程引用/触发SAVE功能:
mymodule.viewModelFunctions.saveModel()
这也意味着(在我的情况下,因为我有3个视图模型,我需要从一个事件触发保存)我可以灵活地保存我想要的时间/方式。显然,将任何错误等等返回给调用模块会很好,但原则上它对我有用。