Най-добра практика за промяна на модела на 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