更改时自动刷新列表视图 - knockoutjs & jQuery 移动版

发布于 2024-12-02 01:17:54 字数 1570 浏览 0 评论 0原文

我正在将 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 }" />

我的 Knockout 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');
}

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

谢谢您的时间。

I am using knockoutjs (very new to it) with JQuery Mobile. I have a listview which I bind filtered results to. After I load my data the first time I have to call

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

in order for JQM to restyle my list, this works great.

However when I filter my list, it is rerendered and looses the style again and I can't figure out where to call the refresh again.

My html is as follows:

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

My Knockout JS is:

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

I am sure that there is something very silly that I am missing...

Thank you for your time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冬天的雪花 2024-12-09 01:17:54

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

This issue has come up on the KO forums a few times.

One option is to create a binding that is bound to your filteredItems and runs the listview refresh.

It could look like:

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

Now, you would place this on the container (or really on any element) and pass in the observable that you want it to depend on like:

<ul data-bind="jqmRefreshList: filteredItems"></ul>
烟柳画桥 2024-12-09 01:17:54

您可以在 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);
    }
};

Can you post the entire working code on jsfiddle ? Because I am having the same issue and I tried your solution but it still not working.

[Edit] : Ok, it worked fine for me like this :

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);
    }
};
若无相欠,怎会相见 2024-12-09 01:17:54

基于前两个答案,这里有一些更完整的内容。 并通过处理异常而不是超时来解决 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.
      }
    }
  }
};

它允许您使用无容器绑定(即注释中的 foreach) , co.uk/blog/colin/2012/10/integrating-knockout-and-jquerymobile/" rel="nofollow">我的博客上的完整工作示例。希望有帮助!

Building on the previous two answers, here is something a little more complete. It allows you to use containerless binding (i.e. foreach within comments), and soles the issue of refresh being fired after the jQM page lifecycle by handling exceptions rather than a timeout:

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.
      }
    }
  }
};

There's a complete worked example up on my blog. Hope that helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文