0

JSON呼び出しから入力されるノックアウトビューモデルがあります。フォームのselect要素には、一連のオプション(これもviewmodelから取得)と値、の一部がありobservableArrayます。問題はselect要素にのみあり、入力要素にはありません。フォームを送信するとき、selectで割り当てられた値のみに適切な値が含まれます。したがって、JSONから正常に読み込まれ、フォームに表示されたものの、変更されていないものは、options配列の最初の値としてサーバーに返送されます。

HTMLフォーム:

<form>
    <table >
        <thead>
            ...
        </thead>
        <tbody data-bind='foreach: ScaledCostEntries'>
            <tr>
                <td><input data-bind='value: StartDateString' class="startdate" type="text"/></td>
                <td><select data-bind='value: InvoiceType, options: $root.InvoiceTypes'></select></td>                    
                <td><a href='#' data-bind='click: $root.removeCost'>Delete</a></td>
            </tr>
        </tbody>

    </table>
    <button data-bind='click: addCost'>Add New Row</button>
    <button data-bind='click: save' >Update</button>
</form>

上記のこのコードでは、問題はビューモデルobservableArrayの一部であるInvoiceTypeにありScaledCostEntriesます。(また、値とオプションの順序を入れ替えると、選択した値がselect要素に配置されません)。

とJS:

<script type="text/javascript">
    $(function () {
        var scaledCostModel = function () {
            var self = this;

            self.ScaledCostEntries = ko.observableArray([]);
            self.InvoiceTypes = ko.observableArray([]);

            self.addCost = function () {
                self.ScaledCostEntries.push({                    
                    StartDateString: ko.observable(),
                    InvoiceType: ko.observable()
                });
            };

            self.removeCost = function (cost) {
                cost.IsDeleted = true;
                self.ScaledCostEntries.destroy(cost);
            };

            self.save = function (form) {
                jQuery.ajax({
                    url: '@Request.Url.PathAndQuery',
                    type: "POST",
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    data: ko.toJSON(self.ScaledCostEntries)                    
                });
            };
        };

        jQuery.getJSON('@Request.Url.PathAndQuery', function (data) {
            ko.mapping.fromJS(data, {}, viewModel);
        });

        var viewModel = new scaledCostModel();

        ko.applyBindings(viewModel);
    });
</script>

したがって、要約すると、問題は、select要素にバインドされたviewmodelのプロパティにあります。InvoiceTypes選択が変更されないままの場合(再選択されない場合)、ビューモデルは、サーバーに投稿するときに、options()配列の最初の項目としてその値を持ちます。結局、私は些細なことを忘れているかもしれません、そしてこれは私の最初のより深刻なknockout.jsの試みです。

注:InvoiceTypeは、の一部ScaledCostEntriesですobservableArrayInvoiceTypesですobservableArrayInvoiceTypesと、はどちらもScaledCostEntriesJSONから取得され、ScaledCostEntries返送されます。

4

1 に答える 1

3

私の仮定は、これはScaledCostEntriesフォーム送信時にサーバー上でどのように処理されているかによるものだと思います。

追加および削除される依存モデルのリストを含むメインモデルがあり、すべてを更新するためにメインモデルに対してフォーム送信が行われるときに、以前に(さまざまなサーバー側フレームワークで)問題が発生しました。

問題は、フォームの送信中に、リクエストの値がサーバー側モデルにマップされているときに、空白の値が「これを削除する」ではなく「変更なし」を意味すると見なされることです。これは、モデルのプロパティで直接機能しますが、依存モデルのリストでは機能しません。

これに対処する方法はいくつかあります。ビューで[削除]または[削除]ボタンが押されたときに、Ajaxを使用して基になるモデルを削除し、メインモデルとの関係を更新します。または、モデルのリスト全体を毎回明示的に送信し、フォームの送信ごとにサーバー上のリストを明示的に削除して再構築します。それぞれがさまざまな状況に適用可能であり、おそらく他のアプローチもうまくいく可能性があります。

于 2013-03-20T14:37:00.983 に答える