Automatically refresh your watchlist when you change - knockoutjs & jQuery Mobile

I am using knockoutjs (very new to it) with jQuery Mobile. I have a listview to which I bind the filtering results. After I upload my data, the first time I have to call

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

so that JQM redid my list, this works fine.

However, when I filter my list, it overwrites and loses style again, and I cannot figure out where to call the update 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 JS knockout:

 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'm sure there is something very stupid that I am missing ...

Thank you for your time.

+6
source share
3 answers

This problem has occurred on the KO forums several times.

One option is to create a binding tied to your filteredItems , and start updating the list.

It might look like this:

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

Now you put this in a container (or indeed on any element) and tell the observable that you want it to depend on:

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

Can you post all jsfiddle working code? Because I have the same problem and I tried your solution, but it still does not work.

[Edit]: Well, it worked 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); } }; 
+3
source

Based on the previous two answers, here is something a little more complete. This allows you to use binding to the container (i.e. Foreach in the comments) and eliminates the update problem that runs after the jQM page life cycle, handling exceptions rather than 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 he completed work on my blog . Hope this helps!

+1
source

Source: https://habr.com/ru/post/896228/


All Articles