【问题标题】:Automatically refresh list view on change - knockoutjs & JQuery Mobile更改时自动刷新列表视图 - knockoutjs & JQuery Mobile
【发布时间】:2011-11-06 23:39:01
【问题描述】:

我在 JQuery Mobile 中使用了 knockoutjs(对它来说非常新)。我有一个列表视图,我将过滤结果绑定到。第一次加载数据后,我必须调用

$('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');
}

我确信我错过了一些非常愚蠢的东西......

感谢您的宝贵时间。

【问题讨论】:

    标签: jquery listview mobile knockout.js


    【解决方案1】:

    这个问题在 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>
    

    【讨论】:

    • 谢谢,我以前遇到过这个,但我不确定如何将此绑定应用到我的 foreach?
    • 真的,你可以把它放在任何元素上,甚至是身体。如果你想把它和你的模板一起保存,那么你可以这样做:data-bind="template: {name: 'myTemplate', foreach: filteredItems }, jqmRefreshList: filteredItems"
    • 非常感谢 RP!工作了一个款待。 BTW knockmeout 是一个很棒的网站。
    • 在我将 $(element).listview("refresh") 包装在 try/catch 中以忽略第一次调用时的初始化问题之后,上述内容对我有用,否则@Niemeyer 的工作很棒!
    【解决方案2】:

    你能把整个工作代码贴在 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);
        }
    };
    

    【讨论】:

    • 这让我免于将笔记本电脑扔出窗外,谢谢!
    • 在我的例子中,我返回了一个 ObservableArray。所以在使用它时,我需要这样做: data-bind="template: {name: 'myTemplate', foreach: filteredItems() }"
    【解决方案3】:

    在前两个答案的基础上,这里有一些更完整的东西。它允许您使用无容器绑定(即 cmets 中的 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。希望对您有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-17
      • 1970-01-01
      • 2014-03-30
      • 2012-03-24
      • 2013-02-13
      • 1970-01-01
      • 2016-12-23
      • 1970-01-01
      相关资源
      最近更新 更多