2

サーバー側のプロパティで追加/削除操作を実行するために、knockout.js を使用しようとしています。私の C# モデルは次のようになります。

public class MyModel
{
    [Key]
    public int MyModelId { get; set; }

    [Required]
    public string Name { get; set; }

    private IEnumerable<string> _Items;

    [Required]
    public IEnumerable<string> Items
    {
        get { return _Items; }
        set { _Items = value; }
    }

    //Used to store in SQL database
    public string ItemsSQL
    {
        get { return _Items != null ? String.Join(";", _Items) : null; }
        set { _Items = value != null ? value.Split(';').ToList() : null; }
    }
}

私のViewModelは次のようになります。

@model MyProject.Models.MyModel

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout-2.1.0.js")" type="text/javascript"></script>
<script type="text/javascript">
    @{
        var initialData = new JavaScriptSerializer().Serialize(Model);
    }
    var viewModel = {
        MyModel: ko.observable(@Html.Raw(initialData)),

        //Commented out on purpose
        //Items: ko.observableArray(this.MyModel.Items),

        addItem: function() { 
            this.MyModel.Items.push("");
        },

        removeItem: function(item) {
            this.MyModel.Items.remove(item);
        },
    };

    alert(JSON.stringify(@Html.Raw(initialData)));

    $(document).ready(function() {ko.applyBindings(viewModel); });
</script>

そして、これが私の見解です:

Name: <span data-bind="text: MyModel().Name"></span>
<br />
Items: <button data-bind="click: addItem">Add Item</button>

<table>
    <tbody data-bind="template: { name: 'itemTemplate', foreach: MyModel().Items}"></tbody>
</table>

<script type="text/html" id="itemTemplate">
    <tr>
        <td>
            <input data-bind="value: $data" />
            <a href="#" data-bind="click: function() { 
                                   viewModel.removeItem($data) }">Remove Item</a>
        </td>
    </tr>
</script>

これは、テキスト ボックスMyModel.Nameに表示される各項目と共にMyModel.Items表示されます。私の問題は、インスタンス化しようとするとItems、エラーメッセージが吐き出されることです。 Unable to get value of the property 'Items': object is null or undefined. これは、追加および削除操作にも影響します。

アップデート

実行するとalert(JSON.stringify(this.MyModel));、MyModel が未定義であることが示されますが、実行するとalert(JSON.stringify(@Html.Raw(initialData)));、モデルが JSON 形式で表示されます。私のモデルは正しくシリアル化されていますが、ノックアウトは C# 変数から監視可能なプロパティを作成できませんか? 知らない。カミソリが痛い。

4

2 に答える 2

5

ViewModel は次のように構築する必要があります。

@{
    var initialData = new JavaScriptSerializer().Serialize(Model);
}
var data = @Html.Raw(initialData);
function ViewModel(data) {
    var self = this;
    self.Name = ko.observable(data.Name);
    self.Items = ko.observableArray(data.Items);
    self.addItem = function() { self.Items.push(""); };
    self.removeItem = function(data) { self.Items.remove(data); }
}
$(document).ready(function() {ko.applyBindings(new ViewModel(data)); });
于 2012-08-30T15:46:33.353 に答える
2

これは C# 変数だと思いinitialDataますが、javascript を介して警告しようとしています。

var かみそりが内部でどのように処理されているかを伝えるのが難しいため、少し混乱します@{ }

文字列化する場合は、最初にそれを javascript 変数に入れる必要があります。何かのようなもの:

var jsInitialData = @{Html.Raw(initialData)}

Razor は JavaScript ブロック内で少し面倒なので、正確には機能しませんが、それらの線に沿ったものが必要だと思います。

于 2012-08-29T15:46:08.050 に答える