如何协调动态KO映射与手动?

时间:2015-05-07 20:07:58

标签: c# asp.net-mvc knockout.js

我经常遇到一种情况,我希望将C#ViewModel映射到视图中的knockout viewModel。

这意味着我通常会做类似的事情:

<script>
    var viewModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model));
</script>

这样可以将C#ViewModel放入我的viewModel中。但我经常希望允许用户以有意义的方式与viewModel进行交互,因此我的模型是List<User>,而User具有属性NameAge。我的观点可能如下:

<table class="table">
    <tbody data-bind="foreach: viewModel">
        <tr>
            <td><input type="text" data-bind="value: Name" /></td>
            <td><input type="text" data-bind="value: Age" /></td>
            <td><span class="glyphicon glyphicon-remove" data-bind="click: Remove"></span></td>
        </tr>
    </tbody>
</table>
<button type="button" data-bind="click: AddUser">Add User</button>

现在我已经有了一个按钮来删除每行中的每个User,但为了提供该功能,我需要为每个Remove方法添加User方法List中的{1}}。这是我的不确定性开始的地方。我一直在做的基本上是:

<script>
    var vm = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model));

    var viewModel = function (vm) {
        var self = {};

        self.Users = vm;

        ko.utils.arrayForEach(self.Users(), function(item) {
            item.Remove = function() 
            {
                self.Users.remove(this);
            }
        });

        self.AddUser = function() {
            self.Users.push({
               Name: "",
               Age: ""
            });
        }
    }

</script>

虽然这样可行(我对此进行了解释,因此可能存在一些错误),但是必须遍历我的映射视图模型以添加所需的函数等等,这似乎过于冗长和笨拙。有没有更清洁的方法来做到这一点,还是我只是挑剔?

1 个答案:

答案 0 :(得分:2)

我会采用另一种方式,并将remove()函数放在viewmodel中:

            Template.modal.helpers({
                products: function () {
                    return Products.find({});
                },
                image:function(){  
                    return productImages.findOne({'metadata.productId':this._id})
                }
            });

然后在你的视图中调用它:

var viewModel = function (vm) {
    var self = {};

    self.Users = vm;

    self.remove = function(item) {
        self.Users.remove(item);
    };

    self.AddUser = function() {
        self.Users.push({
           Name: "",
           Age: ""
        });
    }
}