【问题标题】:Search an observable array using Knockout, Breeze, Durandal使用 Knockout、Breeze、Durandal 搜索可观察数组
【发布时间】:2013-08-09 09:43:21
【问题描述】:

我有以下可观察数组,当视图被激活时(在 Durandal 的 activate() 函数中),它使用 Breeze 从 WebAPI 获取数据

var prices = ko.observableArray();

价格类具有三个属性:id、name和price。

然后我有以下数组:

var services = [{
    active: true,
    name: 'Service1',
    price: getPrice('Service1')
}, {
    active: true,
    name: 'Service2',
    price: getPrice('Service2')
}];

getPrice(name) 函数应该做的是获取名称作为参数传递的对象...

我希望能够在视图上执行以下操作:

<div class="services">
    <ul data-bind="foreach: services">
        <li data-bind="visible: active, text: name + ' ($' + price.price + ')'"></li>
    </ul>
</div>

我在 StackOverflow 上进行了很多搜索,并尝试以多种方式做到这一点,但未能成功。我不确定我是否应该使用 ko.utils.arrayFirst()、ko.computed() 或我应该做什么。我尝试了很多方法但没有成功。

【问题讨论】:

    标签: javascript knockout.js breeze durandal


    【解决方案1】:

    更新 我想我会在 cmets 中添加 MrYellow 的这个答案,以防有人遇到这个问题。

    results = ko.utils.arrayMap(inputs, function(item) { return new ModelFoo(item); });
    

    原创

    您不能在视图中使用该数据,因为它不是可观察的数组,属性也不是可观察的。

    var services = ko.observableArray([{
        active: ko.observable(true),
        name: ko.observable('Service1'),
        // Option 1
        price: ko.observable(getPrice('Service1'))
    }, {
        active: ko.observable(true),
        name: ko.observable('Service2'),
        // Option 2
        price: ko.computed(getPrice(name()))
    }]);
    

    这在您看来是可行的。如果您尝试使用 Breeze 执行此操作,那么您应该已经有了一个 observable,除非出现问题,此时我们将需要更多代码。

    如果您想遍历价格并让服务这样做 -

    var services = ko.observableArray();
    ko.utils.arrayForEach(prices(), function (price) {
        services.push(new service(price.active(), price.name(), price.price());
    });
    

    在这样的地方有一个模型

    function service(active, name, price) {
        var self = this;
        self.active = ko.observable(active);
        self.name = ko.observable(name);
        self.price = ko.computed(getPrice(name));
    }
    

    原因是如果您要创建新的 Knockout 对象(可观察对象),那么您需要遍历 Breeze 结果并制作它们。使用如图所示的模型类型,这样您就可以提高效率并将一切都保持在范围内。

    另一种选择是,如果 price() 除了 price 属性之外已经包含您想要的所有内容,则只需在返回 Breeze 实体以计算价格时创建一个构造方法。

    【讨论】:

    • ko.utils.arrayMap 可能更适合。 results = ko.utils.arrayMap(inputs, function(item) { return new ModelFoo(item); });
    • 是的,可能有几个旧答案我应该回去更新:) 我通常会尽量更新那些仍然获得大量流量的答案
    【解决方案2】:

    你可以使用直接的 JS 来做到这一点:

    var getPrice = function(name) {
    
        var matches = prices().filter(function(x) { return x.name == name; });
    
        if(matches.length == 0) return null;
    
        return matches[0].price;
    };
    

    注意我是prices().filter,因为它是一个 KO 可观察数组,而不是普通数组。

    【讨论】:

    • 谢谢,我遇到的问题(当我尝试了几乎所有方法时也发生了这种情况)是当执行 getPrices(name) 函数时,价格列表仍然没有加载..当我运行 Chrome 开发者控制台时,我可以看到 price() 数组是空的 (Object[0])...
    • 别忘了ko.utils.arrayFilter 也可用。
    【解决方案3】:

    我会使用映射插件 (http://knockoutjs.com/documentation/plugins-mapping.html) 和计算的 observable,它创建价格 observable,而不是作为原始视图模型的一部分。见http://www.underwatergorilladome.com/how-to-use-knockouts-computed-observables-with-the-mapping-plugin/

    【讨论】:

    • 微风不需要映射插件。
    • 唯一详细讨论的技术是 KO。
    猜你喜欢
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 2014-04-13
    • 2013-06-25
    • 2012-12-19
    相关资源
    最近更新 更多