5

Knockout (2.2.0)の背後にある概念を把握しようとしています。
私はASP.NET MVC 4を使用しているので、「複雑な」ビューモデル (マスター詳細) を持つ例に従うことができると思いました。

私が見つけた唯一のものはMvcMusicStoreです。

コードは読みやすく、サーバーからビューモデルを読み取り、クライアントでビューモデルを構築する方法を理解しました。

これは私の C# ViewModelです:

public class Person
{
    public Person()
    {
        this.Phones = new List<Phone>();
    }
    public string Name { get; set; }
    public string Surname { get; set; }
    public int Age { get; set; }

    public IList<Phone> Phones { get; set; }
}

public class Phone
{
    public string Model { get; set; }
    public string Number { get; set; }
}

私のコントローラーは、データが取り込まれたモデルをビューに返し、ノックアウト ビューモデルに変換します。

var data = @Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model));
var model = ko.mapping.fromJS(data);
ko.applyBindings(model);

Rob Conery が使用したのと同じパターンを使用しました。上記のコードは単純化されたバージョンです。

これは私の見解です:

@using (@Html.BeginForm("Index", "Home", FormMethod.Post))
{
    <input id="Name" name="Name" type="text" data-bind="value: Name" value="" />
    <br />
    <input id="Surname" name="Surname" type="text" data-bind="value: Surname" value="" />
    <br />
    <table>
    <tbody data-bind="foreach: Phones">
        <tr>
            <td><input type="text" data-bind='value: Model' /></td>
            <td><input type="text" data-bind='value: Number' /></td>
        </tr>
    </tbody>
    </table>
    <input type="submit" value="Send" />  
}

ここで、フォームを送信し、コントローラーで更新されたビューモデルを読み取りたいと思います。

これを実現するために、MvcMusicStore にあるのと同じソリューションを使用しました。49 行
目を見ると、Rob は FORM をシリアル化しようとしています。

var data = $("#orderForm").serialize();

そしてコントローラへの POST:

$.post("/orders/edit", data, callback);

このコードをビューモデルで機能させることができないようです。私のコントローラー:

[HttpPost]
public JsonResult Index(Models.Person viewModel)
{
...
}

子を逆シリアル化できないようです。クライアント側をデバッグすると、seralizeメソッドもそれらをシリアル化できないことがわかります。

実際、なぜ彼が FORM をシリアライズしようとしているのかわからない。ノックアウトによって管理されるビューモデルがあるためです。このような「複雑な」モデルをシリアル化し、コントローラーに POST できる他の方法はありませんか?

ソリューション ( MvcMusicStore ) が適切に機能していると思いますか、それとも他のパターンに従う必要がありますか?

どんな助けでも大歓迎です。

アップデート

解決策を見つけたと思いますが、さらにテストを行う必要があります。toJSON KO メソッド
を使用する場合:

var data = ko.toJSON(model);

ビューモデル全体を適切にシリアル化できます。次に、$.ajax を使用してデータを POST する必要があります

$.ajax({
    type: 'POST',
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    url: "/Home/Index",
    data: dataToSave,
    success: callback,
    error: function (req, status, error) {
       alert("Status: " + status + " Error: " + error);
      }
});

この方法ですべてがうまくいくように見えますが、それでも、推奨される方法があるかどうか知りたいです。

解決

Michael Berkompas と nemesv は有益な情報を提供してくれました。他の誰かが興味を持った場合に備えて、簡単なアプリケーションをまとめました。

4

2 に答える 2

5

問題は、テーブル内に要素に属性inputがないことです。name

モデルバインディングコレクションの場合、MVCは特別な名前形式を必要とするため、 attrバインディングを使用して名前を設定できます。次のように記述する必要があります。

<tbody data-bind="foreach: Phones">
        <tr>
            <td><input type="text" data-bind="value: Model, attr: { name: 'Phones[' + $Index() + '].Model' }" /></td>
            <td><input type="text" data-bind="value: Number, attr: { name: 'Phones[' + $Index() + '].Number' }" /></td>
        </tr>
</tbody>

または、とにかくビューモデルがあるため、コントローラーに直接送信できます。

var model = ko.mapping.fromJS(data);

//...

$.ajax({
    type: 'POST',
    url: "/orders/edit",
    contentType: "application/json",
    data: ko.mapping.toJSON(model),
    success: callback
});

この場合、「application / json」として$.post指定する必要があるため、使用できないことに注意してください。contentType

しかし、これを行うための推奨される方法はないと思います。$("#orderForm").serialize()(私が言及した適切な入力名を使用して)と動作の両方。ko.toJSON(model)違いは、データがajaxリクエスト用に準備/エンコードされる方法のみであるためです。

どちらを使うかは個人的な好みのようなものだと思います。この特定のケースko.toJSON(model)では、ASP.NET MVCの特別な入力名の生成を処理する必要がないため、この方法を実行する方が適切なようです。ビューモデルをそのままサーバーに送信できます。そして、ノックアウトを使用すると、より自然に感じます。

于 2013-01-03T18:36:06.927 に答える
1

nemesvの2番目のオプションのバリエーションを使用します。jQueryを使用してフォームをシリアル化する代わりに、シリアル化されたビューモデルを投稿します。

データ型が複雑で、Asp.net MVCがそれをビューモデルに変換するのに問題があるため、このページ$.toDictionary()で説明されているプラ​​グインも使用することをお勧めします。

var model = ko.mapping.fromJS(data);

//...

$.post("/orders/edit", $.toDictionary(ko.toJS(model)), callback, "json");
于 2013-01-03T19:52:21.560 に答える