Автоматически обновлять представление списка при изменении - knockoutjs & JQuery Mobile - PullRequest
6 голосов
/ 30 августа 2011

Я использую 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');
}

Я уверен, что есть кое-что очень глупое, что мне не хватает ...

Спасибо, что уделили время.

Ответы [ 3 ]

14 голосов
/ 31 августа 2011

Эта проблема появлялась на форумах КО несколько раз.

Один из вариантов - создать привязку, привязанную к 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>
3 голосов
/ 28 июня 2012

Можете ли вы опубликовать весь рабочий код на 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);
    }
};
1 голос
/ 23 октября 2012

Основываясь на предыдущих двух ответах, здесь есть кое-что более полное. Он позволяет вам использовать привязку без контейнеров (то есть 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.
      }
    }
  }
};

В моем блоге есть полный обработанный пример . Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...