How to prevent Backbone.Marionette from rendering a view if it's model hasn't been fetched?

前端 未结 4 651
暗喜
暗喜 2020-12-31 10:08

In my backbone.Marionette application I have a Model that requires an Id attribute to construct it\'s url. I therefore create the model by passing it an Id, add it to a view

4条回答
  •  执念已碎
    2020-12-31 10:29

    I've recenlty run into the same issue and settled on a pattern of using Marionette's event system to let the views communicate their status before firing show(). I'm also using requireJS which adds some additional complexity - but this pattern helps!

    I'll have one view with a UI element that when clicked, fires an event to load a new view. This could be a subview or a navview - doesn't matter.

    App.execute('loadmodule:start', { module: 'home', transition: 'left', someOption: 'foo' });
    

    That event is caught by the Wreqr 'setHandlers' and triggers a view loading sequence (in my case I'm doing a bunch of logic to handle state transitions). The 'start' sequence inits the new view and passes in necessary options.

    var self = this;
    App.commands.setHandlers({'loadmodule:start': function( options ) { self.start( options );
    

    Then the view getting loading handles the collections / models and fetching on initalize. The view listens for model / collection changes and then fires a new "ready" event using wreqr's executre command.

    this.listenTo( this.model, 'change', function(){
        App.execute('loadmodule:ready', { view: this, options: this.options });
    }); 
    

    I have a different handler that catches that ready event (and options, including the view opject reference) and triggers the show().

    ready: function( options ) {
    
    // catch a 'loadmodule:ready' event before proceeding with the render / transition - add loader here as well
    
    var self = this;
    var module = options.options.module;
    var view = options.view;
    var transition = options.options.transition;
    var type = options.options.type;
    
    if (type === 'replace') {
        self.pushView(view, module, transition, true);
    } else if (type === 'add') {
        self.pushView(view, module, transition);
    } else if (type === 'reveal') {
        self.pushView(view, module, transition, true);
    }   
    
    },
    
    
    pushView: function(view, module, transition, clearStack) {
    
    var currentView = _.last(this.subViews);
    var nextView = App.main.currentView[module];
    var self = this;
    
    var windowheight = $(window).height()+'px';
    var windowwidth = $(window).width()+'px';
    var speed = 400;
    
    switch(transition) {
    case 'left':
    
        nextView.show( view );
    
        nextView.$el.css({width:windowwidth,left:windowwidth});
        currentView.$el.css({position:'absolute',width:windowwidth,left:'0px'});
    
        nextView.$el.animate({translate: '-'+windowwidth+',0px'}, speed, RF.Easing.quickO);
        currentView.$el.animate({translate: '-'+windowwidth+',0px'}, speed, RF.Easing.quickO, function(){
    
            if (clearStack) {
                _.each(_.initial(self.subViews), function( view ){
                     view.close();
                });
                self.subViews.length = 0;
                self.subViews.push(nextView);
            }
    
        });
    
    break;
    

    I'll try to write up a decent gist of the whole system and post here in the next week or so.

提交回复
热议问题