使用Knockout,Breeze,Durandal搜索可观察的数组

时间:2013-08-07 20:25:12

标签: javascript knockout.js breeze durandal

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

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(),或者我应该做什么..我已经尝试了很多方法而没有成功。

3 个答案:

答案 0 :(得分:2)

<强>更新 如果有人遇到这个问题,我会在评论中添加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执行此操作,那么除非出现问题,否则您应该已经有一个可观察对象,此时我们将需要更多代码。

如果你想迭代价格并让服务像这样做 -

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对象(observables),那么你需要迭代Breeze结果并制作它们。使用如图所示的模型类型,这样您就可以高效并将所有内容保持在范围内。

另一个选择是,如果price()已经拥有除price属性之外的所有内容,那么只需在返回Breeze实体计算价格时创建构造函数方法。

答案 1 :(得分:1)

你可以使用直接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可观察数组而不是普通数组。

答案 2 :(得分:-1)

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