18

私は単純な修正でなければならないことにこだわっています。ネストされたビューモデルでノックアウト.jsを使用していますが、削除機能が正しく機能していないことを除いて、すべて問題ないようです。正しくバインドされているように見えますが、削除をクリックしても起動しません。

ビューモデルをネストする理由 長い話ですが、基本的には 1 ページに多くの情報が必要です。

コードは次のとおりです。

HTML

<section class="mini-form-container">
    <form data-bind="submit: repeatGuest.addDate">
        <input type="date" data-bind="value: repeatGuest.previousStay"/>
        <button type="submit" class="button-secondary ">Add date</button>
    </form>
    <div data-bind="foreach: repeatGuest.dates, visible: repeatGuest.dates().length > 0">
        <div>
            <input data-bind="value: date" disabled="disabled"  />
            <a data-bind="click: $parent.removeDate">Remove</a>
        </div>
    </div>
</section>

<section>
    <div data-bind="text: ko.toJSON($data)"></div>
</section>

Javascript

function RepeatGuest() {
    /// <summary>Child View Model</summary>
    this.dates = ko.observableArray();
    this.previousStay = ko.observable();
}

RepeatGuest.prototype.addDate = function () {
        var self = this.repeatGuest;
        if (self.previousStay()) {
            self.dates.push({
                date: self.previousStay()
            });
        }
    };

RepeatGuest.prototype.removeDate = function (date) {
    this.dates.remove(date);
}

function ViewModel() {
    var self = this;
    self.repeatGuest = new RepeatGuest();
}
ko.applyBindings(new ViewModel());

そして、ここに私のフィドルがあります:http://jsfiddle.net/6Px4M/2/

では、なぜ削除機能が起動しないのでしょうか?

考えられる副次的な質問: ネストされたビュー モデルは、ノックアウトを取り入れるのに間違った方法ですか? これに関する情報はあまりないようです。

4

2 に答える 2

24

このようなネストされたモデルを操作する最良の方法の 1 つは、withバインディングを使用することです。できるよ:

<div data-bind="with: repeatGuest">
   ...
</div>

これで、スコープはあなたのものにrepeatGuestなり、そのプロパティに対して直接バインドできます。

あなたのremove機能の問題は、その時点での価値thisと誰であるかに関連し$parentています。関数はthis、現在のスコープと等しい の値で実行されます。remove 関数がバインドされている場合、スコープはdate配列内のオブジェクトの 1 つです。

これを処理する通常の方法は、関数が常に の正しい値を使用するようにバインドすることですthis。これは、次のようなバインディング (非常に醜い) で実行できます。

<a data-bind="click: $parent.repeatGuest.removeDate.bind($parent.repeatGuest)">Remove</a>

より良いオプションは、RepeatGuestコンストラクターのビュー モデルでバインドすることです。

this.removeDate = this.removeDate.bind(this);

これにより、実装がプロトタイプ上に存在し、各インスタンスで正しい値を強制するラッパーで上書きされますthis。または、プロトタイプに配置しない場合は、var self = this;パターンを使用selfしてハンドラーで使用できます。

http://jsfiddle.net/cNdJj/

于 2013-03-01T17:40:05.043 に答える
4

バインドは、間違ったプロトタイプの関数にアクセスしません。現在、RepeatGuest オブジェクトではなく、viewModel にバインドしています。

ローカル関数として設定すると機能します。

http://jsfiddle.net/6Px4M/3/

function ViewModel() {
    var self = this;
    self.repeatGuest = new RepeatGuest();
    self.removeDate = function (date) {
        self.repeatguest.dates.remove(date);
    }
}
于 2013-03-01T17:35:10.550 に答える