Резервный список Backbone.js не обновляется с помощью мобильного телефона jQuery - PullRequest
2 голосов
/ 14 сентября 2011

Я пытаюсь добавить параметры сортировки в список JQM, который поддерживается коллекцией backbone.js.Я могу отсортировать коллекцию (через представление коллекции) и заново отобразить список, но JQM не обновляет список.

Я искал и нашел несколько вопросов, похожих на мой (проблемы с обновлением списка JQM для обновления), но я не смог заставить его работать.

Я пыталсязвонить $(‘#list’).listview(‘refresh’) и $(‘#list-page’).page() и т. д. безрезультатно.Я подозреваю, что, возможно, я вызываю метод обновления не в том месте (на более раннем этапе), но я не уверен, куда еще мне его поместить (я только начинаю с магистрали).

Вотразметка и JS.

HTML:

<div data-role="page" id="Main">
<div data-role="header"><h1>Main Page</h1></div>
<div data-role="content">   
        <ul data-role="listview">
            <li><a href="#Page1">Page 1</a></li>
        </ul> 
</div>
<div data-role="footer"><h4>Footer</h4></div>
</div>

<div data-role="page" id="Page1">
  <div data-role="header">
  <a href="#Main" data-role="back" data-icon="back">Back</a>
  <h1>Items</h1><a href="#dvItemSort" >Sort</a></div>
  <div data-role="content">
    <div id="dvTest">
        <ul id="ItemList" data-role="listview"  data-filter="true"></ul>
    </div>
  </div><div  data-role="footer"><h4>Footer</h4></div></div>

  <div data-role="page" id="dvItemSort">
  <div data-role="header"><h4>Sort</h4></div>
      <a href="#Page1" type="button" 
       name="btnSortByID" id="btnSortByID">ID</a>
      <a href="#Page1" type="button" 
       name="btnSortByName" id="btnSortByName">Name </a>
  </div>

Javascript:

  $(function () {

    window.Item = Backbone.Model.extend({
    ID: null,
    Name: null
});

window.ItemList = Backbone.Collection.extend({
    model: Item
});

window.items = new ItemList;
window.ItemView = Backbone.View.extend({
    tagName: 'li',

    initialize: function () {
        this.model.bind('change', this.render, this);
    },

    render: function () {
        $(this.el).html('<a>' + this.model.get('Name') + '</a>');
        return this;
    }
});

window.ItemListView = Backbone.View.extend({

    el: $('body'),

    _ItemViews: {},

     events: {
        "click #btnSortByID": "sortByID",
        "click #btnSortByName": "sortByName"
    },

    initialize: function () {
        items.bind('add', this.add, this);
        items.bind('reset', this.render, this);
    },

    render: function () {

        $('#ItemList').empty();

        _.each(items.models, function (item, idx) {
            $('#ItemList').append(this._ItemViews[item.get('ID')].render().el);
        }, this);

         $('#ItemList').listview('refresh'); //not working
        // $('#ItemList').listview(); 
        // $('#Page1').trigger('create');
         // $('#Page1').page(); //also doesn't work
    },


    add: function (item) {
        var view = new ItemView({ model: item });
        this._ItemViews[item.get('ID')] = view;
        this.$('#ItemList').append(view.render().el);

    },

    sortByName: function () {
        items.comparator = function (item) { return item.get('Name'); };
        items.sort();
    },

    sortByID: function () {

        items.comparator = function (item) { return item.get('ID'); };
        items.sort();
    }
});

window.itemListView = new ItemListView;

window.AppView = Backbone.View.extend({ 

    el: $('body'),

    initialize: function () {

        items.add([{ID: 1, Name: 'Foo 1'}, {ID:2, Name: 'Bar 2'}]);

    },
});

window.App = new AppView; 

});

РЕДАКТИРОВАТЬ: Я понял, что первая строка разметки HTML, которую я разместил, не былаотображается в моем сообщении, поэтому я нажал его на строку.

РЕДАКТИРОВАТЬ 2: Вот ссылка на jsfiddle кода http://jsfiddle.net/8vtyr/2/

РЕДАКТИРОВАТЬ 3 Глядя на итоговую разметку, кажется, что JQM добавляет некоторые классы к элементам списка.Я попытался добавить их вручную, используя флаг, чтобы определить, был ли список перерисован в результате сортировки, и затем список отображается правильно.

Однако, помимо того, что это некрасивое решение, более важно, что мои магистральные событияв представлении «элемент» больше не срабатывает (в примере кода, который я разместил, я не поместил код для событий, потому что я пытался сделать его как можно более релевантным).

РЕДАКТИРОВАТЬ 4 Я вроде как заработал, очистив кэш просмотров и воссоздав их.Я разместил свой ответ ниже.

РЕДАКТИРОВАТЬ 5 Я обновил свой ответ с тем, что я считаю лучшим ответом.

Ответы [ 2 ]

0 голосов
/ 03 октября 2012

Мне посчастливилось решить эту проблему, но причина для меня остается неясной.

По сути, в верхней части моего представления рендера после установления html() моего элемента я называю listview().Затем любые дополнительные элементы, которые я мог бы добавить к списку, вызывают listview('refresh').

0 голосов
/ 15 сентября 2011

Я не уверен, должен ли это быть его собственный ответ или нет (я немного просмотрел FAQ), поэтому сейчас я просто обновляю свой предыдущий ответ.

Теперь я нашел лучший способ сортировки списка, используя мои кэшированные представления. По сути, дело в том, чтобы отсортировать коллекцию, отделить элементы от DOM и затем снова присоединить их. Итак

Код теперь будет

 $list = $('#ItemList')

 $('li', $list ).detach();
 var frag = document.createDocumentFragment();
 var view;
    _.each(item.models, function (mdl) {
    view = this._ItemViews[item.get('ID')];
        frag.appendChild(view.el);
    },this);

   $list.append(frag);

СТАРЫЙ ОТВЕТ

Я вроде решил проблему. Я проверял визуализированные элементы и заметил, что когда элементы были «перерисованы» (после сортировки), они теряли обработчики событий (я проверил в firebug). Поэтому я решил очистить кэш просмотров и воссоздать их. Кажется, это помогает, хотя я не совсем уверен, почему именно.

Для кода:

Вместо:

  $('#ItemList').empty();
    _.each(items.models, function (item, idx) {
        $('#ItemList').append(this._ItemViews[item.get('ID')].render().el);
    }, this);
     $('#ItemList').listview('refresh'); //not working

Я очищаю кэш представлений и воссоздаю представления.

  $('#ItemList').empty();
        this._ItemViews = {};
        _.each(items.models, function (item, idx) {
            var view = new ItemView({ model: item  });
            this._ItemViews[item.get('ID')] = view;
            this.$('#ItemList').append(view.render().el)           
        }, this);
        $('#ItemList').listview('refresh'); //works now

Я думаю, что было бы лучше, если бы мне не нужно было регенерировать кеш, но по крайней мере это рабочее решение, и если я не получу лучшего ответа, я просто приму это.

...