1

では、コントローラーアクションが事前に入力された値を持つモデルを返す場合、KnockoutJSにそれらをどのように認識させますか?

例えば:

@Html.TextBoxFor(m => m.Title, new { data_bind="value: title"} )

ただし、$(document).ready()knockout.js ViewModelをバインドする場所では、この値はまだ入力されていません。

$(document).ready({
  var viewModel = {
    title: ko.observable($("#Title").val()) // too early for this?!
  }

  ko.applyBindings(viewModel);​
});

KnockoutJSをMVCのモデルバインディングでどのように機能させますか?私が見つけた回避策の1つは、次のようにRazorビューでJavaScript変数を設定することでした。

<script>
  var strTitle = '@Model.Title';
</script>

ノックアウトモデルのバインディングで使用するよりも。それはうまくいきますが、私はそれが嫌いです。フォームに数百のフィールドがある場合はどうなりますか?ページに多くのJavaScript変数は必要ありません。私はここで明白なことを見逃していますか?

4

3 に答える 3

3

これはこの質問に似ているようです。通常、スクリプトで@ModelをJSONに変換して、ビューモデルを設定します。

<script type="text/javascript">
var model = @(new HtmlString(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model)));
</script>

コントロール値に基づいてビューモデルを最初にロードする独自のバインディングハンドラーを作成することもできます。この新しいハンドラーは、 initの初期制御値からビューモデルを更新することを除いて、myvalue基本的に既存のハンドラーを呼び出します。value

ko.bindingHandlers['myvalue'] = {
    'init': function (element, valueAccessor, allBindingsAccessor) {
        // call existing value init code
        ko.bindingHandlers['value'].init(element, valueAccessor, allBindingsAccessor);

        // valueUpdateHandler() code
        var modelValue = valueAccessor();
        var elementValue = ko.selectExtensions.readValue(element);
        modelValue(elementValue); // simplified next line, writeValueToProperty isn't exported
        //ko.jsonExpressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'value', elementValue, /* checkIfDifferent: */ true);
    },
    'update': function (element, valueAccessor) {
        // call existing value update code
        ko.bindingHandlers['value'].update(element, valueAccessor);
    }
};

次に、ko.applyBindingsを呼び出すと、最初はコントロールの値に基づいてobservableが設定されます。

<input type="text" data-bind="myvalue: Title" value="This Title will be used" />
<input type="text" data-bind="value: Title" value="This will not be used" />
<!-- MVC -->
@Html.TextBoxFor(m => m.Title, new { data_bind="myvalue: Title"} )

サンプルフィドル

于 2012-06-21T20:51:41.307 に答える
2

JSON.NETなどを使用してページモデル全体をjsonにシリアル化するのはどうでしょうか。次に、js以外のユーザーの通常のかみそりビューバインディングを介してページにデータが入力されます。次に、ページスクリプトは次のようになります。

<script>
    ko.applyBindings(@Html.ToJSON(Model));
</script>

または、型付きのviewModelがある場合

<script>
    var viewModel = new MyViewModel(@Html.ToJSON(Model));
    ko.applyBindings(viewModel);
</script>

クライアント側と実際のビューモデルを同じように構成することは理にかなっているため、json形状を操作する必要はありません。

編集

toJSONヘルパーの例。

public static MvcHtmlString ToJson(this HtmlHelper html, object obj)
{
  JavaScriptSerializer serializer = new JavaScriptSerializer();
  return MvcHtmlString.Create(serializer.Serialize(obj));
}

お役に立てれば。

于 2012-06-21T18:07:55.957 に答える
2

Jason Goemaatの回答にコメントを追加するという50ポイントの評判がないため、ここに回答としてコメントを追加することにしました。

すべてのクレジットはJasonGoemaatに送られます。

コードを機能させることができませんでした。だから私は小さな変更を加えなければなりませんでした。

        ko.bindingHandlers['myvalue'] = {
    'init': function (element, valueAccessor, allBindingsAccessor) {
        //get initial state of the element            
        var modelValue = valueAccessor();
        var elementValue = ko.selectExtensions.readValue(element);

        // call existing value init code
        ko.bindingHandlers['value'].init(element, valueAccessor, allBindingsAccessor);

        //Save initial state
        modelValue(elementValue);
    },
    'update': function (element, valueAccessor) {
        // call existing value update code
        ko.bindingHandlers['value'].update(element, valueAccessor);
    }
};

この線が一番上にあるとしたら、

// call existing value init code
ko.bindingHandlers['value'].init(element, valueAccessor, allBindingsAccessor);

要素の元の状態を削除していました。したがって、入力フィールドにある値が何であれ、それは削除されていました。

モデルの中に私はこれを持っています:

//publishing comment
self.publishingComment = ko.observable();

そして私のMVCはこのように見えます

@Html.TextBoxFor(model => model.Comment, new { data_bind = "myvalue: publishingComment" })
于 2015-06-04T13:46:04.807 に答える