Rendering a closed Marionette view

2019-04-30 10:09发布

问题:

Shouldn't a closed Marionette view re-delegate the defined events (events, modelEvents, CollectionEvents) when rendering again?

It seems as if I have to manually call delegateEvents after closing and re-rendering a view. Otherwise the view won't work as expected.

http://jsfiddle.net/4DCeY/

var app = new Marionette.Application();

app.addRegions({
    main: '.main'
});

var MyView = Marionette.ItemView.extend({

    template: _.template('Hi, I\'m a view! Foo is: <%= foo %>'),

    modelEvents: {
        'change': 'onChange'
    },

    onChange: function() {
        alert('change!');
    }
});


var Model = Backbone.Model.extend({});


app.addInitializer(function() {
    var m = new Model({foo: 'bar'});
    var myView = new MyView({
        model: m
    });

    app.main.show(myView);
    myView.close();
    app.main.show(myView);

    m.set({foo: 'baz'});

});

$(document).ready(function(){
    app.start();
});

回答1:

If I understand your question right, there are multiple open github issues about this.

For example:

https://github.com/marionettejs/backbone.marionette/pull/654 https://github.com/marionettejs/backbone.marionette/issues/622

Last time I checked, Derick (the creator of Marionette) didn't feel like reusing closed views should be something regions should do.

So you could

  1. simply create a new view and show that one
  2. manually call delegateEvents - but there was an issue with multiple event bindings that I can't remember right now, so be careful about that one (not at work right now, so can't take a peek at the code, sorry)
  3. write your own region manager
  4. or wait and see if Derick will merge one of the pull requests


回答2:

a couple of points:

  1. You do not need to call myView.close() Marionette Region will take care of that when you show another view
  2. Marionette.Region will not replace the same view with itself. It will just skip the redundant procedure if you want to test this correctly you need 2 views
  3. If you want a change in model to invoke render you must explicitly write it

I altered the jsfiddle with the following things:

  1. added myView1 and myView2
  2. removed explicit call to myView.close
  3. added a call for this.render() from the onChange function

Here is the corrected jsfiddle http://jsfiddle.net/4DCeY/1/ :

app.addInitializer(function() {
   var m = new Model({foo: 'bar'});
   var myView1 = new MyView({
      model: m
   });
   var myView2 = new MyView({
      model: m
   });

   app.main.show(myView1);
   app.main.show(myView2);

   m.set({foo: 'baz'});

});

And:

onChange: function() {
    alert('change!');
    this.render();
}