2013-10-31 69 views
0

我正在使用knockout并希望使用arrayFilter来返回其中另一个数组中的属性“修改”的值具有true的对象的数组。使用ko.utils.arrayfilter根据内部集合的值返回集合

即 我的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} 
} 

阵列滤波器的结果将是(如下)监守子汤姆已修改=真

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

这可能吗?

+0

所以你想让你的过滤器列表包含任何'Family',其中*至少有一个*孩子有'Modified = true'?当然是有可能的。你有什么尝试?你有什么问题? –

+1

是的,是的,这是可能的。 –

回答

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利用其观察者优化,而不是每次评估函数时都创建一个新的数组。希望这可以帮助!

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); 
+1

关于此函数的一个注意事项是:在遍历Children节点时,使用arrayFirst查找修改的子节点的第一个实例。这将为您节省一些不必要的周期。 –

+0

忘记arrayFirst,谢谢。编辑答案。 – pax162

+0

这工作很好,我怎么修改返回,只有那些改变的子元素? ty FamilyTree Family { LastName = Smith Children { Name = tom,Modified = true} } – David