Рекомендации по изменению модели Marionette.ItemView

В моем приложении у меня есть CollectionView с ItemView рядом с ним (они оба видны одновременно). При щелчке элемента в списке ItemView отображает его сведения.

Простое решение — запустить

bigLayout.itemDetailsRegion.show(new ItemDetailsView({
   model: modelOfClickedItem
});

Но это делает экземпляр ItemView, который ранее отображался, закрытым и сборщиком мусора, в то время как новый экземпляр того же класса создается и отображается в том же месте. Для меня и моей команды это пахнет плохой практикой (удаление и повторное создание представления кажется нам бесполезными накладными расходами), но правы ли мы?

На данный момент мы добавили метод changeModel(model) в класс ItemView, который

  • отвязывает события от предыдущей модели
  • присваивает новую модель представлению
  • перерисовывает вид
  • привязывает новые события к модели

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

Есть ли что-то, что мы могли бы назвать «лучшей практикой» для такого рода потребностей? Является ли стандартный способ (как описано выше) хорошей практикой?


person xBill    schedule 14.04.2014    source источник


Ответы (1)


Честно говоря, я не понимаю, почему ваш первый подход был бы плохим. Это почти то же самое, что вы делаете вручную, используя метод changeModel.

Я полагаю, что самым «дорогим» действием является повторная визуализация представления (манипуляция с DOM), что вам придется делать в любом случае.

Другой способ, который я могу придумать, это (используя http://nytimes.github.io/backbone.stickit/< /а>):

// Create a stickit marionette itemView
var stickitItemView = Backbone.Marionette.ItemView.extend({
    bindings: {},
    render: function(){
        // Invoke original render function
        var args = Array.prototype.slice.apply(arguments);
        var result = Marionette.ItemView.prototype.render.apply(this, args);

        // Apply stickit
        this.stickit();

        // Return render result
        return result;
    }
});

/* Setup a temp model in an itemView.
 * Several ways to do this, either define all attributes again or 
 * clone an existing model for example. In this case I assume you only want to display 
 * data from the model. If you want to modify it as well you'll have to keep a reference.
 * See: http://stackoverflow.com/questions/17517028/how-to-clone-models-in-backbone
/*
var viewInstance = new stickitItemView({
    model: realModel.clone(),
    template: someTemplate,
    bindings: {
        '.some-element': 'attribute1',
        '.another-element': 'attribute2'
    }
});

// Show the view
someRegion.show(viewInstance);

// Use a another model to update the temp model's attributes. 
viewInstance.model.set(anotherRealModel.toJSON());    

Если я прав, это вполне масштабируемо, предположительно быстрее обновляет ваш DOM (протестируйте!) и заботится о привязке данных.

person Wilbert van de Ridder    schedule 15.04.2014
comment
вы подтверждаете наше подозрение, что перерисовка DOM на самом деле является самой дорогой операцией. Мне нравится ваш ответ (недостаточно репутации, чтобы поставить +1, извините... :) - person xBill; 15.04.2014
comment
Пожалуйста! Как я уже указывал, такие библиотеки, как stickIt, могут быть легче в части манипулирования DOM. Дайте нам знать, что вы в конечном итоге используете :) - person Wilbert van de Ridder; 15.04.2014
comment
Добавил небольшой пример - person Wilbert van de Ridder; 15.04.2014