2011-08-30 57 views
6

我正在使用jQuery Mobile的knockoutjs(非常新)。我有一個listview過濾結果綁定到。第一次加載我的數據後,我必須致電自動刷新列表視圖 - knockoutjs&JQuery Mobile

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

爲了讓JQM重新調整我的清單,這個工程很棒。

但是,當我過濾我的列表時,它被重新渲染並再次失去樣式,我無法找出再次調用刷新的位置。

我的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的綁定並運行列表視圖刷新。

它可能看起來像:

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

非常感謝RP!工作過一種享受。 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。我需要做: data-bind =「template:{name:'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。希望有所幫助!