Cheng Yong
Cheng Yong

Reputation: 33

Marionette 2.0 ViewDestroyedError: Cannot use a view thats already been destroyed

Recently i have upgraded to Marionette 2.0.3

I realised that i have been getting

ViewDestroyedError: Cannot use a view thats already been destroyed error

After searching this error, i realised this is due to re rendering of my view.

Below is my current code:

  View.ElementPanel = Marionette.ItemView.extend({          
     //shorten as example
     triggers: {
       'click .js-show': "element:show",

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


  var elementsPanelView = new View.ElementsPanel({
    collection: elements
  });

  activityView.elementsListPanel.show(elementsPanelView);

  elementsPanelView.on("childview:element:show", function(args, element) {
    LessonManager.trigger("element:show", activityView.elementPanel, activity, element);
  });

i realised that reference to the view is destroyed when the model is re-rendered when there is an attribute change. Therefore rendering elementsPanelView.on("childview:element:... ) listener failing as elementsPanelView is essentially being destroyed when there is a change to my model.

I realised from this github post https://github.com/marionettejs/backbone.marionette/issues/1510 that i should not kept a reference of a view around as that is considered bad code. However, that would means i would not be able to handle the trigger events as i was using a reference of the view elementsPanelView.on("childview:element:show"... ) to intercept the trigger event.

Any help on this?

Upvotes: 3

Views: 2649

Answers (1)

Paul Falgout
Paul Falgout

Reputation: 121

I am not quite following the issue with the reference to the view from the code you've shown, but I do have a suggestion. Where you are re-rendering the view based on the model change you might try looking at whether it is destroyed or not:

this.listenTo(this.model, 'change', function(){
    console.log(this.isDestroyed);
    if(this.isDestroyed) return;
    this.render();
});

If that console log is ever true you'll be calling a render on a destroyed view which would give you that error. You can get into this circumstances when something on the model can also destroy the view via it's parent..

One other thing possibly worth mentioning...

Your childview: event will pass the childview as the first argument and a jQuery event object as the 2nd.

Upvotes: 2

Related Questions