2011-08-30 6 views
6

JQuery Mobile에서 knockoutjs (매우 새로운 것)를 사용하고 있습니다. 필터링 된 결과를 바인딩하는 listview가 있습니다. 내가 처음 내 데이터를로드 한 후 나는 JQM 내 목록 스타일을 다시 지정하기 위해변경시 자동으로 목록보기 새로 고침 - knockoutjs 및 JQuery Mobile

$('ul').listview('refresh'); 

전화를해야이 잘 작동합니다.

그러나 목록을 필터링하면 다시 렌더링되고 스타일이 다시 손실되므로 새로 고침을 다시 호출 할 위치를 파악할 수 없습니다. 다음과 같이

내 HTML은 다음과 같습니다

<p>Filter: <input data-bind="value: filter, valueUpdate: 'afterkeydown'" /></p> 
    <ul data-role="listview" data-theme="g" data-bind="template: {name: 'myTemplate', foreach: filteredItems }" /> 

내 녹아웃 JS입니다 : 내가 놓친 게 매우 어리석은 일이 있다는 것을 확신

var car = function (name, make, year) { 
    this.name = name; 
    this.make = make; 
    this.year = year; 
} 

var carsViewModel = { 
    cars: ko.observableArray([]), 
    filter: ko.observable() 
}; 

//filter the items using the filter text 
carsViewModel.filteredItems = ko.dependentObservable(function() { 
    var filter = this.filter(); 
    if (!filter) { 
     return this.cars(); 
    } else { 
     return ko.utils.arrayFilter(this.cars(), function (item) { 
      return item.make == filter; 
     }); 
    } 
}, carsViewModel); 

function init() { 
    carsViewModel.cars.push(new car("car1", "bmw", 2000)); 
    carsViewModel.cars.push(new car("car2", "bmw", 2000)); 
    carsViewModel.cars.push(new car("car3", "toyota", 2000)); 
    carsViewModel.cars.push(new car("car4", "toyota", 2000)); 
    carsViewModel.cars.push(new car("car5", "toyota", 2000));   
    ko.applyBindings(carsViewModel); 
    //refresh the list to reapply the styles 
    $('ul').listview('refresh'); 
} 

...

감사 당신은 당신의 시간 동안.

답변

14

이 문제는 KO 포럼에 몇 번 나왔습니다.

하나의 옵션은 filteredItems에 바인딩 된 바인딩을 만들고 listview 새로 고침을 실행하는 것입니다.

그것은처럼 보일 수있다 : 이제

ko.bindingHandlers.jqmRefreshList = { 
    update: function(element, valueAccessor) { 
     ko.utils.unwrapObservable(valueAccessor()); //just to create a dependency 
     $(element).listview("refresh"); 
    } 
    }; 

, 당신은 컨테이너에 배치 (또는 정말 모든 요소에) 당신이 그것을 같은에 의존하려는 관측에 전달할 것 :

<ul data-bind="jqmRefreshList: filteredItems"></ul> 
+0

감사합니다. 이전에 건너 왔지만이 바인딩을 내 foreach에 적용하는 방법을 모르겠습니다. – jimjim

+0

정말이 요소를 신체, 심지어 모든 요소에 넣을 수 있습니다. 템플릿과 함께 보관하고 싶다면 다음과 같이하면됩니다 :'data-bind = "template : {name : 'myTemplate', foreach : filteredItems}, jqmRefreshList : filteredItems" –

+0

감사합니다. 치료를 했어. BTW knockmeout은 훌륭한 사이트입니다. – jimjim

3

jsfiddle에 전체 작업 코드를 게시 할 수 있습니까? 내가 동일한 문제를 겪고 있기 때문에 귀하의 솔루션을 시도했지만 여전히 작동하지 않습니다.

는 [편집] : 여기에, 이전 두 답변에

ko.bindingHandlers.jqmRefreshList = { 
    update: function (element, valueAccessor) { 

     ko.utils.unwrapObservable(valueAccessor()); //just to create a dependency 
     setTimeout(function() { //To make sure the refresh fires after the DOM is updated 
      $(element).listview(); 
      $(element).listview('refresh'); 
     }, 0); 
    } 
}; 
+0

이렇게하면 노트북을 창밖으로 던지지 않아도됩니다. 감사합니다! –

+0

제 경우에는 ObservableArray를 반환했습니다. 그래서 그것을 사용하는 otder에, 나는 할 필요 = 데이터 바인딩을 "템플릿 : {이름 : '에 MyTemplate', foreach 문 : filteredItems()}" – Adaptabi

1

건물을 좀 더 완전한 뭔가 : 좋아,이 같은 나를 위해 잘 일했다. 그것은 (즉, foreach는 의견에서) 당신이 바인딩 컨테이너가를 사용할 수 있으며, 새로 고침의 문제가 아니라 시간 제한보다 예외를 처리하여 JQM 페이지 수명주기 후 해고 발바닥 :

ko.virtualElements.allowedBindings.updateListviewOnChange = true; 
ko.bindingHandlers.updateListviewOnChange = { 
    update: function (element, valueAccessor) { 
    ko.utils.unwrapObservable(valueAccessor()); //grab dependency 

    var listview = $(element).parents() 
          .andSelf() 
          .filter("[data-role='listview']"); 

    if (listview) { 
     try { 
     $(listview).listview('refresh'); 
     } catch (e) { 
     // if the listview is not initialised, the above call with throw an exception 
     // there doe snot appear to be any way to easily test for this state, so 
     // we just swallow the exception here. 
     } 
    } 
    } 
}; 

complete worked example up on my blog있다. 희망이 도움이됩니다!

관련 문제