在Backbone.js + Require.js中使用路由器绑定和呈现集合视图的正确方法

时间:2013-11-12 19:58:20

标签: javascript backbone.js requirejs

人们!

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

所以,这是我先做的事情:

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

sampleView.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(new)

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但我不知道这是否是最好的方法,或者有更好的方法。任何人都有建议采取更好的方法,或者我做得对吗?

谢谢,无论如何!

1 个答案:

答案 0 :(得分:0)

你不应该反复重复同一个集合。但只有当您需要来自服务器的一些新数据时。

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

router.js(new)

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&amp; home 应该只能创建一次。

此外,您可能希望在收藏中收听addremovereset events

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