2

最近几天我一直在研究以下 KnockoutJS 问题。

我有一个带有 3 个视图模型的页面。我正在使用带有 id 的 div 来指定绑定,即:

ko.applyBindings(new viewModel(datasource), $("#sectionQualifications")[0]);

我还在使用 RequireJS,它确实有助于使我的应用程序模块化,并且当然可以与 KnockoutJS 很好地配合使用。

我的问题与我的页面上有(如前所述)3 个视图模型有关。没有重叠,但每个视图模型都有一个 SAVE 功能。快速浏览一下其中一个视图模型片段:

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;
    };

因此,从上面的示例中,我将有 2 个其他类似的视图模型,它们具有上述 SAVE 功能。所以当然我想使用说jQuery来单击一个按钮并保存所有3个视图模型(即通过每个视图模型的那个SAVE函数)。

因为我使用的是 RequireJS,所以我尝试公开一个“公共”函数,该函数又尝试在内部调用 viewModel.save() 函数,如下所示:

function saveModel() {
    viewModel.save();

}

//  PUBLIC INTERFACE
return {
    saveModel: saveModel,
    loadViewModel: koMapData
}

所以理论是我可以从应该触发保存视图模型的任何地方调用“saveModel”函数?

任何帮助都非常感谢。顺便说一句,我已经走上了尝试创建视图模型的道路,例如:

var viewModel = {

    save: function() {
        blah blah...
    }
}

但是也没有真正的运气?我确定我错过了一些简单的东西,因为我认为您可以/应该能够以某种方式从外部触发视图模型的功能?

编辑 仅供参考,模型不重叠..

在此先感谢大卫。

4

2 回答 2

2

您可以像这样在对象中合并视图模型:

var mainVModel = {
    vModel1: { // has save method},
    vModel2: { // has save method},
    saveAll : function(){
        mainVModel.vModel1.save();
        mainVModel.vModel2.save();
    }
}

ko.applyBindings(new mainVModel());
于 2013-01-10T10:56:29.853 回答
0

实际上感谢@XGreen 的建议,我可以看到效果很好,但是我使用的是requirejs,所以我的应用程序结构不太匹配。

但是,我在以下解决方案中取得了成功:

首先,我以稍微不同的方式创建了视图模型..

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

所以定义了视图模型,然后我有一个辅助函数来访问视图模型的 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 个视图模型,我需要从一个事件中触发保存)我可以灵活地保存何时/如何保存。显然,最好将任何错误等返回给调用模块,但原则上这对我来说是这样的。

于 2013-01-18T15:54:00.753 回答