0

我正在使用淘汰赛并希望使用 arrayFilter 返回对象数组,其中另一个数组中的“修改”属性的值为 true。

即我的 json 对象看起来像

Family tree
Family{
  LastName=Smith
  Children{
    Name=bob,
    Modified=false},
   {
    Name=tom, Modified=true}
 }
Family{
  LastName=Jones
  Children{
    Name=bruno,
    Modified=false},
   {
    Name=mary, Modified=false}
 }

数组过滤器的结果将是(如下)因为 child tom 已修改 =true

FamilyTree
  Family{
  LastName=Smith
  Children{
    Name=bob,
    Modified=false},
   {
    Name=tom, Modified=true}
 }

这可能吗?

4

2 回答 2

4

我认为@pax162 提供的解决方案可能会回答您的问题。但是,存在使用问题。建议的解决方案将执行嵌套迭代。如果您只希望处理一次数据(而不是驱动一些富客户端视图),那么这是可以采用的方法。另一方面,如果您将此数据绑定到视图,您可能会考虑另一种更类似于 KO 的方法。这是我的想法:

var family = function(data){
    var self = {
        LastName :ko.observable(data.LastName),
        Children : ko.observableArray( data.Children || [])
    };

    family.hasModifiedChildren = ko.computed(function() {
        return ko.utils.arrayFirst(this.Children(), 
            function(child) {
                return child.Modified === true;
            }) !== null;
    }, family);

    return self;
}

与其使用 JSON 数据,不如创建可观察的 JS 对象,如下所示:

var families = return ko.utils.arrayMap(familiesJson, family);
// or, if you need an observable:
families = ko.observableArray(ko.utils.arrayMap(familiesJson, family));

最后,获取您的家庭名单,这些家庭有这样的修改过的孩子:

var familiesWithModifiedChildren = ko.computed(function() { 
    return ko.utils.arrayFilter(families, function(fam) {
        return fam.hasModifiedChildren();
    });
});

如果您正在构建实时更新页面,您将希望使用这种样式的视图模型。这将允许 Knockout 利用其观察者优化,而不是每次评估函数时都构建一个新数组。希望这可以帮助!

于 2013-10-31T16:13:47.273 回答
1

如果您只想获得至少有一个修改过的孩子的家庭,您可以这样做(http://jsfiddle.net/MAyNn/3/)。json 无效,稍作更改。

 var families = [
{
    LastName :"Smith",
    Children : [{
    Name:"bob",
    Modified:false},
   {
       Name:"tom", Modified :true}
 ]
},
{
    LastName :"Jones",
    Children : [{
    Name:"bruno",
    Modified:false},
   {
       Name:"mary", Modified :false}
 ]
}   
 ];

var filteredFamilies = ko.utils.arrayFilter(families, function(family){
    var hasModified = false;
    var first = ko.utils.arrayFirst(family.Children, function(child){
        return child.Modified;
    })
    if (first) {
        hasModified = true;
    }

    return hasModified;
})

console.log(families);
console.log(filteredFamilies);
于 2013-10-31T15:28:49.930 回答