如何设计MarionetteJS ItemView以正确显示加载消息?

时间:2013-05-20 20:22:12

标签: backbone.js marionette backbone-views

首先 - 我是MarionetteJS菜鸟。

我无法让ItemView在获取时显示加载消息或throbber。当从Backbone的历史记录中的深层链接显示此ItemView时,这尤其成问题(即,ItemView是自用户直接链接到应用程序以来显示的应用程序的第一页)。我想指出页面正在加载(获取),最好是使用简单的视图,然后使用获取的模型显示真实的模板化视图。

我已经在Marionette.async上看到了其他答案(已被弃用)并在ItemView.initalize()期间更改了模板。

任何人(德里克?)在这里得到了任何建议或最佳做法?

更新:

我使用collection.get(id)从集合中获取模型,而不是直接使用model.fetch()。

在考虑了这个之后,真正的问题是应该在哪里实施:

  • 我可以更改我的控制器以查看模型是否存在于集合中(如果集合已加载)并决定相应显示哪个视图。这看起来像是很多模板,因为任何ItemView和任何控制器都可能发生这种情况。

  • 我可以更改我的ItemView初始化以测试模型是否存在(以及加载的集合),但这里的注释相同:每个ItemView都可能出现此问题。

    < / p>

    更新2: 这就是我最终的结果,以防其他人想要这个解决方案:

    app.ModelLayout = Backbone.Marionette.Layout.extend({  
        constructor: function(){  
            var args = Array.prototype.slice.apply(arguments);    
            Backbone.Marionette.Layout.prototype.constructor.apply(this, args);    
            // we want to know when the collection is loaded or changed significantly    
            this.listenTo(this.collection, "reset sync", this.resetHandler);    
        },    
        resetHandler: function () {    
            //  whenever the collection is reset/sync'ed, we try to render the selected model    
            if (this.collection.length) {    
                // when there is no model, check to see if the collection is loaded and then try to get the    
                // specified id to render into this view    
                this.model = this.collection.get(this.id);    
            }    
            this.render();    
        },    
        getTemplate: function(){    
            // getTemplate will be called during render() processing.  
            // return a template based on state of collection, and state of model    
            if (this.model){    
                // normal case: we have a valid model, return the normal template    
                return this.template;    
            } else if (this.collection && this.collection.isSyncing) {    
                // collection is still syncing, tell the user that it is Loading    
                return this.loadingView;    
            } else {    
                // we're not syncing and we don't have a model, therefore, not found    
                return this.emptyView;    
            }    
        }    
    });    
    

    以下是如何使用它:

    // display a single model on a page
    app.Access.Layout.CardLayout = app.ModelLayout.extend({
        regions: {
            detailsRegion:"#detailsRegion",
            eventsRegion:"#eventsRegion"
        },
        template:"CardLayout",  // this is the normal template with a loaded model
        loadingView:"LoadingView",  // this is a template to show while loading the collection
        emptyView:"PageNotFoundView",  // this is a template to show when the model is not found
        onRender : function() {  
            this.detailsRegion.show( blah );  
            this.eventsRegion.show( blah );  
        }
    });
    

    谢谢!

  • 2 个答案:

    答案 0 :(得分:1)

    对于ItemView

    我认为你可以在你的初始化函数中添加一个微调器,我真的很喜欢spin.js http://fgnass.github.io/spin.js/,因为它非常简单易用,你可以在Itemview的onRender函数中隐藏微调器

    对于CollectionView

    在CollectionView中你可以像这样处理....

    看看Derick发布的解决方案.. https://github.com/marionettejs/backbone.marionette/wiki/Displaying-A-%22loading-...%22-Message-For-A-Collection-Or-Composite-View

    答案 1 :(得分:0)

    我建议使用jQuery deferreds:

    1. 开始获取数据,并存储返回值(这是一个jQuery承诺)
    2. 实施内容视图
    3. 显示加载视图
    4. 当承诺为done时,显示包含内容的视图
    5. 我已经谈过在我的博客上实现这项技术:

      Rayweb_on链接的解决方案的问题是,您的加载视图将在您的集合为空时显示(即不仅仅是在获取它时)。此外,ItemView没有emptyView属性,因此无论如何它都不适用于您的案例。

      更新

      根据您更新的问题,您仍然可以通过动态指定要使用的模板来应用该概念:https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.view.md#change-which-template-is-rendered-for-a-view

      然后,当/如果数据已成功获取,则在视图中触发重新渲染。