Mam Marionette CompositeView z panelem wyszukiwania i zbieraniem danych wynikowych.

Chciałbym wywołać funkcję, gdy:

  • wyrenderowany zostanie panel wyszukiwania.
  • kolekcja nie jest jeszcze renderowana.
  • ta funkcja nie powinna być wywoływana podczas renderowania kolekcji.

Zrobiłem to w ten sposób: (ale funkcja "afterRender" została wywołana dwukrotnie)

// VIEW
App.MyComposite.View = Backbone.Marionette.CompositeView.extend({
    // TEMPLATE
    template: Handlebars.compile(templates.find('#composite-template').html()),
    // ITEM VIEW
    itemView: App.Item.View,
    // ITEM VIEW CONTAINER
    itemViewContainer: '#collection-block',

    //INITIALIZE
    initialize: function() {        
        this.bindTo(this,'render',this.afterRender);
    },

    afterRender: function () {
        //THIS IS EXECUTED TWICE...
    }

});

W jaki sposób mogę to zrobić?

======EDYTUJ======================== ============

Rozwiązałem to w ten sposób, jeśli masz spostrzeżenia, daj mi znać.

// VIEW
App.MyComposite.View = Backbone.Marionette.CompositeView.extend({

    //INITIALIZE
    initialize: function() {        
        //this.bindTo(this,'render',this.afterRender);
        this.firstRender = true;
    },

    onRender: function () {
        if (firstRender) {
            //DO STUFF HERE..............
            this.firstRender = false;         

        }
    }

});
5
Jaime Rivera 31 sierpień 2012, 02:05

2 odpowiedzi

Najlepsza odpowiedź

Marionette udostępnia metodę onRender wbudowaną we wszystkie jej widoki, dzięki czemu możesz pozbyć się wywołania this.bindTo(this, 'render', this.afterRender):


// VIEW
App.MyComposite.View = Backbone.Marionette.CompositeView.extend({
    // TEMPLATE
    template: Handlebars.compile(templates.find('#composite-template').html()),
    // ITEM VIEW
    itemView: App.Item.View,
    // ITEM VIEW CONTAINER
    itemViewContainer: '#collection-block',

    //INITIALIZE
    initialize: function() {        
        // this.bindTo(this,'render',this.afterRender); // <-- not needed
    },

    onRender: function () {
        // do stuff after it renders, here
    }

});

Aby jednak nie działał, gdy kolekcja nie jest renderowana, musisz dodać logikę do metody onRender, która sprawdza, czy kolekcja została wyrenderowana.

Zależy to w dużej mierze od tego, co próbujesz zrobić z renderowaniem, gdy żadne elementy z kolekcji nie są renderowane.

Na przykład... jeśli chcesz wyrenderować komunikat „Nie znaleziono elementów”, możesz użyć wbudowanej konfiguracji emptyView dla widoku złożonego.


NoItemsFoundView = ItemView.extend({
  // ...
});

CompositeView.extend({

  emptyView: NoItemsFoundView

});

Ale jeśli masz jakiś specjalny kod, który trzeba uruchomić i zrobić pewne rzeczy, które nie są objęte tą opcją, będziesz musiał wprowadzić własną logikę.


CompositeView.extend({

  onRender: function(){
    if (this.collection && this.collection.length === 0) {
      // do stuff here because the collection was not rendered
    }
  }

});
11
Derick Bailey 31 sierpień 2012, 17:46

Po prostu użyj funkcji onShow

Backbone.Marionette.ItemView.extend({
  onShow: function(){
    // react to when a view has been shown
  }
});

http://marionettejs.com/docs/marionette.view.html#view-onshow

5
nothing-special-here 1 kwiecień 2015, 19:27