我正在使用Backbone Marionettes CollectionView。我试图表明集合正在加载,todo所以我使用emptyView来显示一个加载器。
然而,这是错误的逻辑,因为有时候集合是空的,因此它变成了一个破坏的加载器。
我尝试使用此脚本,但它不起作用:https://github.com/surevine/marionette-loadingview-plugin
有没有人有更好的解决方案?继承了我目前的代码:
//loadingview
define(["marionette", "text!app/templates/loading.html"], function(Marionette, Template) {
"use strict";
return Backbone.Marionette.ItemView.extend({
template: Template
});
})
//collection
define(["marionette", "text!app/templates/events/collection.html", "app/collections/events", "app/views/events/item", 'app/views/loading'], function (Marionette, Template, Collection, Row, LoadingView) {
"use strict"
return Backbone.Marionette.CompositeView.extend({
template: Template,
itemView: Row,
itemViewContainer: "ul",
emptyView: LoadingView,
initialize: function () {
this.collection = new Collection()
return this.collection.fetch()
}
})
})
//item
define(["marionette", "text!app/templates/events/item.html"], function(Marionette, Template) {
"use strict";
return Backbone.Marionette.ItemView.extend({
template: Template,
tagName: "li"
})
})
答案 0 :(得分:4)
我通常会听取Collection / Model的'request'和'sync'事件。像这样:
var View = Backbone.Marionette.CompositeView.extend({
template: Template,
itemView: Row,
itemViewContainer: "ul",
collectionEvents: {
'request': 'showLoading',
'sync': 'hideLoading'
},
initialize: function () {
this.collection = new Collection();
return this.collection.fetch();
}
showLoading: function() {
this.$el.addClass('loading');
},
hideLoading: function() {
this.$el.removeClass('loading');
}
});
答案 1 :(得分:1)
您可以在计划显示视图的元素中提供一些静态HTML。静态内容将在页面加载时显示,当模型成功返回数据时,您将显示视图,从而覆盖静态内容。
查看这个演示它的jsFiddle。静态内容只是说“正在加载......”但当然你可以用旋转器gif和所有它来制作你喜欢的。 http://jsfiddle.net/tonicboy/5dMjD/6/
HTML:
<header>
<h1>A Marionette Playground</h1>
</header>
<article id="main">LOADING...</article>
<script type="text/html" id="sample-template">
Store name: <span> <%= venue.name %> </span>.
</script>
代码:
// Define the app and a region to show content
// -------------------------------------------
var App = new Marionette.Application();
App.addRegions({
"mainRegion": "#main"
});
// Create a module to contain some functionality
// ---------------------------------------------
App.module("SampleModule", function (Mod, App, Backbone, Marionette, $, _) {
// Define a view to show
// ---------------------
var MainView = Marionette.ItemView.extend({
template: "#sample-template"
});
// Move this to outside the Controller
// as this gives access to other Views
// Otherwise you would have to declare a New Model inside every controller
var Book = Backbone.Model.extend({
url: 'https://api.foursquare.com/v2/venues/4afc4d3bf964a520512122e3?oauth_token=EWTYUCTSZDBOVTYZQ3Z01E54HMDYEPZMWOC0AKLVFRBIEXV4&v=20130808',
toJSON: function () {
return _.clone(this.attributes.response);
}
})
// Define a controller to run this module
// --------------------------------------
var Controller = Marionette.Controller.extend({
initialize: function (options) {
this.region = options.region;
this.model = options.model;
// Listen to the change event and trigger the method
// I would prefer this as this is a cleaner way of binding and
// handling events
this.listenTo(this.model, 'change', this.renderRegion);
},
show: function () {
this.model.fetch();
},
renderRegion: function () {
var view = new MainView({
el: $("#main"),
model: this.model
});
this.region.attachView(view);
this.region.show(view);
}
});
// Initialize this module when the app starts
// ------------------------------------------
Mod.addInitializer(function () {
// I would create the model here and pass it to the controller
var myBook = new Book();
Mod.controller = new Controller({
region: App.mainRegion,
model: myBook
});
Mod.controller.show();
});
});
// Start the app
// -------------
App.start();