2012-03-17 5 views
1

저는 Knockout.js를 처음 접했고 지금 상황에 직면하고 있습니다. 어떻게해야 제대로 처리 할 수 ​​있는지 알 수 없습니다. 것은 : 나는 아약스를 통해 검색하는 객체들을 가지고있다. 결과는 다소 다음과 같이 될 것입니다 :knockout.js로 중첩 배열을 관리하고 렌더링하는 방법은 무엇입니까?

내가 지금까지했던 어떤
var Objects = [ { id: 0, name: "Foo", type: "A" }, 
       { id: 1, name: "Bar", type: "B" }, 
       { id: 1, name: "Bar", type: "A" }, ... ]; 

(간체) :

var ViewModel = function() { 
    var self = this; 
    self.objects = ko.observableArray(Objects); 
}; 

가 지금은 자신의 "유형"에 따라 다른 목록에 해당 개체를 렌더링 할 필요가있다. 따라서 "A"유형의 객체 목록과 "B"유형 객체에 대한 목록이 있습니다 (현재 5 가지 유형이 있지만 앞으로 추가 될 수 있습니다).

var ViewModel = function() { 
    var self = this; 
    self.objects = ko.observableArray(Objects); 

    self.objectsA = ko.computed(function() { 
     return ko.utils.arrayFilter(self.objects(), function(item) { 
      return (item.type == 'A'); 
     }); 
    }); 

    self.objectsB = ... 
    self.objectsC = ... 
}; 

그리고 내 실제보기 :이 문제를 해결하기 위해 더 나은 방법이

<h1>Type A</h1> 
<ul class="typeA" data-bind="template: { name: 'object', foreach: objectsA }"></ul> 

<h1>Type B</h1> 
<ul class="typeB" data-bind="template: { name: 'object', foreach: objectsB }"></ul> 

있습니까

나는이 (작업) 솔루션을 함께 왔어요? 이것은 작동하지만 약간 추한 것이지, 실제로는 역동적 인 것은 아니며 많은 반복을 포함합니다.

답변

5

바인딩은 computed observable 내부에서 실행됩니다. 즉, 원하는 경우 실제 매개 변수가 아닌 computed observable이 아닌 간단한 함수를 사용하도록 선택할 수 있습니다.

다음
var ViewModel = function() { 
    var self = this; 
    self.objects = ko.observableArray(Objects); 

    self.filterByType = function(type) { 
     return ko.utils.arrayFilter(self.objects(), function(item) { 
      return (item.type === type); 
     }); 
    }; 
}; 

, 그것은에 대한 바인딩이 좋아 :

<h1>Type A</h1> 
<ul class="typeA" data-bind="template: { name: 'object', foreach: filterByType('A') }"></ul> 

<h1>Type B</h1> 
<ul class="typeB" data-bind="template: { name: 'object', foreach: filterByType('B') }"></ul> 
배열을 조작 할 때마다 지금 업데이트됩니다 귀하의 UI가 (항목이 추가

/제거

은 당신이 그것을 아래로 단순화 할 수 있다는 것을 의미). 그러나 type을 즉석에서 편집하려는 경우 type은 계산 된 관찰 가능 항목을 관찰 가능하도록 업데이트해야합니다 (원래 방법 또는 이런 방식으로). 여기

샘플 : http://jsfiddle.net/rniemeyer/NFbxc/

+0

덕분에 모든 것이 훨씬 명확 해졌습니다. 나는 이걸로 갈거야! – Niko

1

당신은 그냥 할 수있는 마네는 다음과 같이 필터링을 수행

<h1>Type A</h1> 
<ul class="typeA" data-bind="template: { name: 'object', foreach: objects }"> 
    <li data-bind="if: type = 'A'"><!--whatever mark-up you wanted here--></li> 
</ul> 

그리고 다른 유형의 동일 않습니다. 또는 ViewModel에 여러 유형의 배열을 보유하고 하나의 템플릿으로 전체 작업을 수행 할 수도 있습니다.

편집 : RP 메이어의 답변을 포함, 당신은이 작업을 수행 할 수 있습니다 :

var ViewModel = function() { 
    var self = this; 
    self.objects = ko.observableArray(Objects); 
    self.types = ["A","B","C","D"]; 

    self.filterByType = function(type) { 
     return ko.utils.arrayFilter(self.objects(), function(item) { 
     return (item.type === type); 
     }); 
    }; 
}; 

<!-- ko foreach types --> 
    <h1> Type <span data-bind="text: $data"></h1> 
    <ul data-bind="{attr: {class = 'type' + $data}, template: { name: 'object', foreach: filterByType($data)}}"></ul> 
<!-- /ko --> 

이제 타입 E를 추가

이 유형의 당신을 배열에 "E"를 추가로 간단합니다.

+0

두 개의 중첩 된 foreach 루프처럼 말입니까? 그게 가능하니? – Niko

+0

@ 니코 : 네. 것이 가능하다 –

관련 문제