简体   繁体   English

如何针对这种情况构造Knockout JS(使用ASP.NET MVC)

[英]How to structure Knockout JS for this scenario (Using ASP.NET MVC)

I'm just starting Knockout. 我刚刚开始淘汰赛。 On my View I have a list of Cars displayed. 在我的视图中,显示了汽车列表。

What is the best way to initially populate the JS array for cars and also subsequently, what is the best way to store the list in JS for lookups, adding, removing etc. 最初是为汽车填充JS数组的最佳方法是什么,随后又是在JS中将列表存储以进行查找,添加,删除等的最佳方法是什么?

As far as I see it, there are a few options for initially populating: 据我所知,最初填充有一些选项:

  • A1. A1。 Output a JSON string from .NET that my Knockout uses to populate a Car array. 从.NET输出一个JSON字符串,我的Knockout用来填充一个Car数组。
  • A2. A2。 Have a data-id="x" attribute on each Car element, which Knockout uses to populate. 在每个Car元素上都有一个data-id =“ x”属性,Knockout用于填充该属性。

And there are a few options for storing the data in knockout: 还有一些用于将数据存储在剔除中的选项:

  • B1. B1。 The Viewmodel has an array of indicies (referring to the .NET ids) and an array for each property of the object. Viewmodel有一个索引数组(指.NET id)和该对象的每个属性的数组。
  • B2. B2。 The Viewmodel has an array of custom JS objects (cars), which then has properties like id,color, type etc. Viewmodel具有一组自定义JS对象(汽车),然后具有id,color,type等属性。

Which is the best way to handle these situations. 这是处理这些情况的最佳方法。 I'm guessing A1 & B2? 我在猜A1和B2? I'm a bit worried about the lookup on B2 being slow, because it will require a custom iterator to find objectWithID(x) 我有点担心在B2上的查找速度很慢,因为它将需要一个自定义的迭代器才能找到objectWithID(x)

My suggestion would be A1 and B2. 我的建议是A1和B2。 Because of how knockout works the lookups won't be an issue in most cases. 由于敲除的工作方式,在大多数情况下查找都不是问题。 Knockout also has several util helpers to assist on such operations, read this post http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html . Knockout也有几个util助手来协助进行此类操作,请阅读此帖子http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html

I created this fiddle to show you how I would have structured it: http://jsfiddle.net/ts8DW/ 我创建了这个小提琴,以向您展示如何构建它: http : //jsfiddle.net/ts8DW/

<script>
    var carsArrayDataFromServer = [
        {
            name: 'audi', 
            color: 'red'
        },
            {
            name: 'volvo', 
            color: 'blue'
        },
        {
            name: 'toyota', 
            color: 'green'
        }
    ];
    var CarModel = function (data) {
        this.name = data.name;
        this.color = data.color;
    };

    var ViewModel = function(carsArray) {
        var self = this;

        self.cars = ko.observableArray([]);

        self.delete = function(item) {
            self.cars.remove(item);
        };

        self.init(carsArray);

    };
    ViewModel.prototype = {
        init: function(data) {
            if (!data) return;
            var self = this;
            ko.utils.arrayForEach(data, function(item) {
                self.cars.push(new CarModel(item));
            });
        }
    };

    ko.applyBindings(new ViewModel(carsArrayDataFromServer), document.getElementById('cars-app'));
</script>

<div id="cars-app">
    <ul data-bind="foreach: cars">
        <li>
            <span data-bind="text: name"></span>
            <a href="#" data-bind="click: $parent.delete">
                Delete
            </a>
        </li>
    </ul>
</div>

The easiest way to deal with lists of complex data from the server is using the Knockout mapping plugin . 处理来自服务器的复杂数据列表的最简单方法是使用Knockout映射插件

Using dynamic data-x HTML attributes defies the purpose of Knockout, which is to populate static HTML (a template) with data. 使用动态data-x HTML属性违反了Knockout的目的,即用数据填充静态 HTML(模板)。 Use Ajax to request your data model from the server instead. 使用Ajax从服务器请求您的数据模型。

function CarViewModel(data) {
    var self = this, 
        loaded = new Date();

    ko.mapping.fromJS(data, {}, self);

    self.displayName = ko.computed(function () {
        return [data.color, data.year, data.make, data.model].join(" ");
    });
}

function CarListViewModel() {
    var self = this;

    self.cars = ko.observableArray();

    self.load = function () {
        $.get("cars.json")
        .then(function (data) {
            var carMapping = {
                key: function (data) {
                    return ko.utils.unwrapObservable(data.id);
                },
                create: function (options) {
                    return new CarViewModel(options.data);
                }
            };
            ko.mapping.fromJS(data, carMapping, self.cars);
        });
    };
}

ko.applyBindings(new CarListViewModel());

(Note that this example depends on jQuery for the Ajax requests.) (请注意,此示例取决于jQuery的Ajax请求。)

See this fiddle for a demonstration/explanation: http://jsfiddle.net/Tomalak/Pbh6S/ 有关演示/说明,请参见此提琴: http : //jsfiddle.net/Tomalak/Pbh6S/

You might also be interested in a similar answer I wrote earlier: dynamic column and rows with knockoutjs 您可能还对我之前写过的类似答案感兴趣: 动态列和带有淘汰表的行

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM