0

伙计们!

我一直在使用 Backbone.js + Require.js 来构建应用程序。在应用程序中,我有路由器和一些绑定到集合的视图。render()同步集合后触发视图的方法。

所以,这是我首先做的:

路由器.js

define([
  'jquery',
  'underscore',
  'backbone',
  'collections/sampleCollection',
  'views/sampleView',
], function($, _, Backbone, SampleCollection, SampleView){
  var AppRouter = Backbone.Router.extend({
    routes: {
      // Define some URL routes
      '': 'home'
    },
    initialize: function(){ ... },
    home: function(){
      var home = new SampleView({collection: SampleCollection});    
    }  
});

(...)

});

sampleCollection.js

define([
  'jquery',
  'underscore',
  'backbone',
  '../models/SampleModel'
], function($, _, Backbone, SampleModel){

  var SampleCollection = Backbone.Collection.extend({
    url: 'url/to/api/call',
    model: SampleModel,
  });

  var sample_collection = new SampleCollection;
  sample_collection.fetch();

  // Our module now returns our collection
  return sample_collection;
});

示例视图.js

define([
  'jquery',
  'underscore',
  'backbone',
  // Using the Require.js text! plugin, we are loaded raw text
  // which will be used as our views primary template
  'text!templates/sample.html'
], function($, _, Backbone, SampleTemplate){
  var SampleView = Backbone.View.extend({
    el: $('#main'),
    initialize: function(){
      this.listenTo(this.collection, 'sync', this.render);
      this.sampleList = this.collection;
      
    },
    render: function(){
      // Using Underscore we can compile our template with data
      var data = { ... };
      var compiledTemplate = _.template( SampleTemplate, data );
      // Append our compiled template to this Views "el"
      this.$el.html( SampleTemplate );

      var string = '';

      this.sampleList.each(function(item){
        string += ('<div>data1: ' + item.get('data1') + ', data2: ' + data.get('data2') + ... +'</div>');
      });

      this.$el.append(string);

    }
  });

  // Our module now returns our view
  return SampleView;
});

首先触发路由,sync从集合中触发,监听后渲染视图sync。问题是,当我更改为另一个视图并再次返回此视图时,该视图不会呈现并且sync不会再次触发,因为在sampleCollection.js中会获取一次集合。

为了更改它并在每次点击该路线时渲染视图,我对代码进行了以下更改:

router.js(新)

define([
  'jquery',
  'underscore',
  'backbone',
  'collections/sampleCollection',
  'views/sampleView',
], function($, _, Backbone, SampleCollection, SampleView){
  var AppRouter = Backbone.Router.extend({
    routes: {
      // Define some URL routes
      '': 'home'
    },
    initialize: function(){ ... },
    home: function(){

      var sample_collection = new SampleCollection;
      sample_collection.fetch();

      var home = new SampleView({collection: sample_collection});    
    }  
});

(...)

});

... 和...

sampleCollection.js(新)

define([
  'jquery',
  'underscore',
  'backbone',
  '../models/SampleModel'
], function($, _, Backbone, SampleModel){

  var SampleCollection = Backbone.Collection.extend({
    url: 'url/to/api/call',
    model: SampleModel,
  });

  return SampleCollection;
});

呸!那是很多代码!

通过这些更改,现在呈现视图,因为每次我点击路由时,都会获取一个新集合并触发sync. 但我不知道这是否是最好的方法,或者有更好的方法。有人对更好的方法有建议,还是我做得对?

不管怎么说,还是要谢谢你!

4

1 回答 1

0

你不应该一次又一次地重新感染同一个集合。但仅当您需要来自服务器的一些新数据时。

home因此,如果您想在每次触发“home”路由时重新渲染列表(aka ),只需render()再次 home(它已经保存了数据/集合):

router.js(新)

define([
  'jquery',
  'underscore',
  'backbone',
  'collections/sampleCollection',
  'views/sampleView',
], function($, _, Backbone, SampleCollection, SampleView){


  // Unique instances (private)
  var sample_collection = new SampleCollection,
      home = new SampleView({collection: sample_collection});

  sample_collection.fetch();

  var AppRouter = Backbone.Router.extend({
    routes: {
      // Define some URL routes
      '': 'home'
    },
    initialize: function(){ ... },
    home: function(){

      // Whether it holds the data or not render the view.
      // It will be re-rendered anyway when `sync` will be triggered
      home.render();
    }  
  });

(...)

});

注意sample_collection&home 应该只创建一次。

此外,您可能想在您的收藏中收听add, remove,reset 事件:

this.listenTo(this.collection, 'reset', this.render);
this.listenTo(this.collection, 'add', this.renderOneItem); // To be defined
this.listenTo(this.collection, 'remove', this.removeOneItem); // To be defined
于 2013-11-13T03:33:50.983 回答