2

私はここ数日、次のKnockoutJSの問題を調査してきました。

3つのビューモデルがあるページがあります。バインディングを指定するためにidを持つdivを使用しています。

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

また、RequireJSを使用しています。これは、アプリをモジュール化するのに非常に役立ち、もちろんKnockoutJSでもうまく機能します。

私の質問は、(前述のように)私のページに3つのビューモデルがあることに関するものです。重複するものはありませんが、各ビューモデルにはSAVE機能があります。したがって、ビューモデルスニペットの1つを簡単に見てみましょう。

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関数を持つ類似した他の2つのビューモデルがあります。したがって、もちろん、jQueryを使用してボタンをクリックし、3つのビューモデルすべてを保存します(つまり、それぞれのSAVE関数を使用します)。

RequireJSを使用しているため、このスニペットで次のようにviewModel.save()関数を内部的に呼び出そうとする「public」関数を公開しようとしました。

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()

これはまた、(私の場合、1 つのイベントから保存をトリガーする必要がある 3 つのビューモデルがあるため) いつ/どのように保存するかを柔軟に設定できることを意味します。明らかに、呼び出し元のモジュールまでエラーなどを返すのは良いことですが、原則としてそれが私にとってどのように機能するかです。

于 2013-01-18T15:54:00.753 に答える