2011-08-30 68 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。希望有所帮助!