2013-12-15 134 views
5

下面是我已经手动构建的集合的当前代码结构。我在我的服务器上有一个json文件,我现在正在尝试加载,基本上删除手动文件并基于该数据构建一个集合。想知道我可能需要在下面更改我的代码以适应此问题。从外部JSON骨干填充集合

 var Game = Backbone.Model.extend({ 
      defaults: { 
       name: 'John Doe', 
       age: 30, 
       occupation: 'worker' 
      } 
     }); 


     var GameCollection = Backbone.Collection.extend({ 
      model: Game, 
      url: 'path/to/json', 

      parse: function(response) { 
       return response; 
      } 
     }); 

     var GamesView = Backbone.View.extend({ 
      tagName: 'ul', 

      render: function() { 
       //filter through all items in a collection 
       this.collection.each(function(game){ 
        var gameView = new GameView({model: game}); 
        this.$el.append(gameView.render().el); 
       }, this) 

       return this; 
      } 
     }); 

     var GameView = Backbone.View.extend({ 
      tagName: 'li', 

      template: _.template($('#gameTemplate').html()), 

      render: function() { 
       this.$el.html(this.template(this.model.toJSON())); 
       return this; 
      } 
     }); 

     var gameCollection = new GameCollection([ 
      { 
       name: 'John Doe', 
       age: 30, 
       occupation: 'worker' 
      }, 
      { 
       name: 'John Doe', 
       age: 30, 
       occupation: 'worker' 
      }, 
      { 
       name: 'John Doe', 
       age: 30, 
       occupation: 'worker' 
      } 
     ]); 

     var gamesView = new GamesView({collection: gameCollection}); 

     $(document.body).append(gamesView.render().el); 
+0

所以你现在说'新的GameCollection(some_big_array_of_stuff)',但现在你想从服务器加载集合? –

+0

是的,我不想使用我为测试创建的手动对象数组,但我现在想尝试加载服务器上的json对象并尝试解析该数据。不知道如何去做。 – Anks

回答

10

这是关于Backbone的许多事情之一。我不知道你用于后端的是什么,但是你声明你的服务器上有一个json文件,希望这个json文件中包含应该在你的集合中的模型。现在这里是魔法代码(请滚动..):

var GameCollection = Backbone.Collection.extend({ 
    model: Game, 
    url: 'path/to/json/on/external/server', 
}); 

var gameCollection = new GameCollection(); 
gameCollection.fetch(); 

不是很多,对不对?当然,您可以添加或更改为fetch的几个选项,因此请在此处查看文档:http://backbonejs.org/#Collection-fetch。骨干网使用jQuery.ajax()是默认的,所以在这里检查出的文档,看看所有的选项:http://api.jquery.com/jQuery.ajax/

你不应该需要您的收藏在自定义解析,除非你在服务器上的型号不匹配您的骨干机型。

事情要知道fetch是异步的。与服务器交谈需要时间,其余的JavaScript将继续并完成。您可能需要至少为success选项添加回调函数,fetch完成后将调用该函数,并且在error中添加某些内容以防出错。您可以将数据添加为查询字符串,以便您的后端可以使用data选项,数据必须是一个对象。这里有一个例子:

gameCollection.fetch({ 
    data: {collection_id: 25}, 
    success: function(){ 
    renderCollection(); // some callback to do stuff with the collection you made 
    }, 
    error: function(){ 
    alert("Oh noes! Something went wrong!") 
    } 
}); 

fetch应该接收数据的JSON,所以您的网址应该是独占返回JSON或设立检测一个AJAX请求,并把它与JSON响应。

+0

没错。但是对于一个(可能的)初学者来说,棘手的部分是'fetch'是一个AJAX调用,并且你需要将'render'附加到某些事件(比如说'reset'或隐藏在'success'回调后面的东西]。 –

+0

@ muistooshort,好点,我会给答案增加一些提示。 – RustyToms

+1

应该这样做。如果OP让收听者设置了一个可以在没有回调的情况下工作的变化,但是我认为在大多数情况下都需要回调。 – RustyToms

1

首先,您需要从RustyToms所说的服务器中获取它。另一个考虑是如何强制收集视图再次呈现自己从服务器收集数据,如muistooshort评论。

如果您操纵fetchsync,则需要在应用程序中存在多个集合时多次执行此操作。

做这样是天然的牵线木偶,但在平原骨干,你可以模仿木偶的的CollectionView的方法,做这样的:

//For the collection view 
var GamesView = Backbone.View.extend({ 
    initialize: function({ 
    this.listenTo(this.collection, 'reset', this.render, this); 
    }); 
    // Others 
}); 

然后,当从服务器获取收集数据,收集将触发reset事件,集合视图注意到这个事件并再次呈现自己。

对于多个集合,您可以将代码提取到应用程序中的父对象中并从中继承。

var App.CollectionView = Backbone.View.extent({ 
    initialize: //code as above 
}); 

var GamesView = App.CollectionView.extend({ 
    //Your code without initialize 
}); 
0

我知道在这一点上这有点老,但想要回答任何其他人卡在这一点。

的代码似乎来自这里找到的教程:http://codebeerstartups.com/2012/12/a-complete-guide-for-learning-backbone-js/

我也重新利用该教程中找到的演示应用程序,并遇到了麻烦,使用外部数据进行渲染。

第一件事是数据本身需要转换为有效的JSON,否则你会得到.parse()错误。

SyntaxError: JSON.parse: expected property name or '}' at line 3 column 9 of the JSON data 

error: SyntaxError: Unexpected token n 

在数据源文件,对象的属性必须用引号引起来。它应该是这个样子:

[ 
    { 
    "name": "John Doe", 
    "age": 30, 
    "occupation": "worker" 
    }, 
    { 
    "name": "John Doe", 
    "age": 30, 
    "occupation": "worker" 
    }, 
    { 
    "name": "John Doe", 
    "age": 30, 
    "occupation": "worker" 
    } 
] 

其次,一次很明显的外部数据加载,我们需要把它呈现。我通过将render()命令移动到gameCollection.fetch()的成功函数中解决了这个问题(可能不太合乎情理)。

gameCollection.fetch({ 
    success: function(collection, response, options) { 
    console.log('Success!! Yay!!'); 
    $(document.body).append(gamesView.render().el); 
    }, 
    error: function(collection, response, options) { 
    console.log('Oh, no!'); 
    // Display some errors that might be useful 
    console.error('gameCollection.fetch error: ', options.errorThrown); 
    } 
}); 

当然,还有更好的方法来做到这一点,但这种方法直接转换代码在本教程获悉到的东西,与外部数据的工作。