1

首先 - 我是 MarionetteJS 菜鸟。

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

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

有人(Derrick?)在这里有任何建议或最佳实践吗?

更新:

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

考虑到这一点,真正的问题是应该在哪里实现:

  • 我可以更改我的控制器以查看模型是否存在于集合中(以及集合是否已加载)并决定相应地显示哪个视图。这似乎到处都是样板,因为这可能发生在任何 ItemView 和任何控制器上。

  • 我可以更改我的 ItemView 初始化以测试模型(和加载的集合)是否存在,但这里有相同的评论:每个 ItemView 都可能有这个问题。

    更新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 );  
        }
    });
    

    谢谢!

  • 4

    2 回答 2

    1

    对于 ItemView

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

    对于 CollectionView

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

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

    于 2013-05-20T20:26:20.157 回答
    0

    我建议使用 jQuery 延迟:

    1. 开始获取您的数据,并存储返回值(这是一个 jQuery 承诺)
    2. 实例化您的内容视图
    3. 显示您的加载视图
    4. 当 promise 是done时,显示包含内容的视图

    我已经在我的博客上谈到了实现这种技术:

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

    更新:

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

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

    于 2013-05-20T20:50:48.577 回答