5

我正在使用骨干木偶 CollectionView。我试图表明集合正在加载,所以我正在使用 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"
  })
})
4

2 回答 2

4

我通常做的是收听 Collection/Model 的“请求”和“同步”事件。像这样的东西:

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');
  }
});
于 2013-09-27T15:00:50.803 回答
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();
于 2013-09-27T15:02:06.883 回答