In backbone marionette is there a way to tell if a

2019-06-20 07:55发布

问题:

Given something like this:

View = Backbone.Marionette.ItemView.extend({ });

myView = new View();

//region already exists
myLayout.region.show(myView)

//some time later this gets called again:
myLayout.region.show(myView)

I can see currentView in the docs but this only seems to apply at initialisation. Once a view is shown can I query the region to see the view? Either the view instance or type would be helpful. Looking in Chrome's debugger I can't see any properties/methods on the region that would help.

The motive for wanting to do this is so I don't show a static item view in a region again if it is already displayed as this can (especially if images are involved) cause a slight flickering effect on the screen.

Thanks

--Justin Wyllie

回答1:

you can add a condition before calling show method:

if (myLayout.region.currentView != myView)
    myLayout.region.show(myView)

so if you'll try to call show with the same View it wont be shown.

if you want to call region.show(myView) once you can check in this way:

if (_.isUndefined(myLayout.region.currentView))
    myLayout.region.show(myView)


回答2:

You can check the isClosed and $el attributes of the view. Something like

if (myView.isClosed || _.isUndefined(myView.$el)) {
  myLayout.region.show(myView);
}

This is the same way the region checks to see if the view is closed or not:

show: function(view) {

  this.ensureEl();

  var isViewClosed = view.isClosed || _.isUndefined(view.$el);
  ...


回答3:

I'm going out on a limb here and assuming that the OP's question is based on app behavior when navigating to different parts of the app via an anchor tag in the navigation or something similar.

This is how I found the question and I thought briefly that the answers would save my day. Although both answers so far are correct they do not quite solve the problem I was having. I wanted to display a persistent navigation bar. However, I did not want it to display on the login page. I was hopeful that detecting if a Region was already shown or not I'd be able to properly let the display logic take care of this.

As it turns out we were both on the right track to implement Regions as this provides granular control, but even after implementing the above I found that my nav bar would still "flicker" and essentially completely reload itself.

The answer is actually a bit ridiculous. Somehow in all the Backbone tutorials and research I've been doing the last two weeks I never came across the need to implement a javascript interface to interrupt normal link behavior. Whenever a navigation item was clicked the entire app was reloading. The routing was functioning so the content was correct, but the flicker was maddening.

I added the following to my app.js file right after the Backbone.history.start({pushState: true}); code:

// Holy crap this is SOOO important!
$(document).on("click", "a[href^='/']", function(event) {
  if (!event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
    event.preventDefault();
    var url = $(event.currentTarget).attr("href").replace(/^\//, "");
    Backbone.history.navigate(url, { trigger: true });
  }
});

Check out this article for some explanation about the keyPress detection stuff. http://dev.tenfarms.com/posts/proper-link-handling

Boom! After adding this stuff in my app no longer completely reloads!

Disclaimer: I am very new to Backbone and the fact that the above was such a revelation for me makes me think that I may be doing something wrong elsewhere and this behavior should already exist in Backbone. If I've made a giant error here please comment and help me correct it.