在更改时自动刷新列表视图 - knockoutjs& JQuery Mobile

时间:2011-08-30 16:42:17

标签: jquery listview mobile knockout.js

我正在使用jout Mobile的knockoutjs(非常新的)。我有一个listview,我将筛选结果绑定到。我第一次调用

后加载数据
$('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');
}

我确信我遗失了一些非常愚蠢的东西......

感谢您的时间。

3 个答案:

答案 0 :(得分:14)

这个问题已经在KO论坛上出现了几次。

一个选项是创建绑定到filteredItems的绑定并运行listview刷新。

它可能看起来像:

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

现在,您可以将它放在容器上(或者实际放在任何元素上)并传入您希望它依赖的observable:

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

答案 1 :(得分: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);
    }
};

答案 2 :(得分: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。希望有所帮助!