2013-10-31 71 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