2011-09-09 104 views
28

令人沮丧的是,backbone.js应用程序的大多数“教程”示例都假设了一个干净的模型。 I-.E。模型集合最初是空的,直到用户添加一个项目。当然,在真实世界的应用程序中,情况并非如此,在这种应用程序中,您通常会从后端存储中获取现有的集合。Backbone.js:渲染真实世界中的应用程序

我想知道人们是如何处理现有的骨干收藏。具体来说:

  • 如何在fetch ed之后​​渲染集合?这仅仅是一个迭代集合的例子吗?这是否应该由某个事件触发?

  • 骨干文档讨论'bootstrapping',我理解的意思是使用初始加载时可用的数据(从SEO角度来看这也是有意义的)。但是,这在实践中如何工作?数据被转储到服务器端的JS?或者JS检查DOM?

我觉得这是一个很差的问题,但我希望根据答案进行扩展。

编辑

如此看来,共识是将数据添加为JS的党和过程,页面上的负荷。

我用这种技术看到的一个很大的缺点是信息不适用于搜索引擎蜘蛛。从这个角度来看,从DOM中提取它可能会更好(虽然我没有看到有人这样做)。或者,也许加入HTML服务器端将数据粘在JS中?

+1

有关使用Backbone进行引导的更多信息,请参阅官方文档:http://documentcloud.github.com/backbone/#FAQ-bootstrap –

+1

@Rilely - 我已阅读文档。但谢谢:) – UpTheCreek

+0

数据被转储到js。 –

回答

11

我遇到了和你一样的情况,我并不总是希望最初引导我的数据(特别是如果它来自第三方api调用)。我还没有遇到任何这样做的教程,但通过文档查看其实非常简单。你只需要在你的集合和渲染上绑定'重置'事件(当整个集合被重新填充时触发)。下面是一个简单的例子:

my_application。JS

window.MyApplication = { 
    Models: {}, 
    Collections: {}, 
    Views: {}, 
    Routers: {}, 
    init: function() { 
    // Start the data loading 
    this.someItems = new MyApplication.Collections.Items(); 
    this.someItems.fetch(); 

    // Start rendering the UI before the data is ready 
    new MyApplication.Routers.Items(this.someItems); 
    Backbone.history.start(); 
    } 
}; 

路由器/ items_router.js

MyApplication.Routers.Items = Backbone.Router.extend({ 
    routes: { 
    "" : "index" 
    }, 

    initialize: function(collection) { 
    this.collection = collection; 
    }, 

    index: function() { 
    var view = new MyApplication.Views.ItemsIndex({ collection: this.collection }); 
    $('.items').html(view.render().el); 
    } 
}); 

的意见/项目/ items_index.js

MyApplication.Views.ItemsIndex = Backbone.View.extend({ 
    initialize: function() { 
    _.bindAll(this, "render"); 

    // Once the collection is fetched re-render the view 
    this.collection.bind("reset", this.render); 
    }, 

    render: function() { 
    console.log(this.collection.length); 
    // Render content 
    return this; 
    } 
}); 
10

至于渲染集合,是的,我通常迭代集合并为每个模型创建一个子视图。这里有一个链接可能对你有帮助http://liquidmedia.ca/blog/2011/02/backbone-js-part-3/

你应该什么时候渲染它?那么这是一个难以回答的问题,但我不会说这是对任何特定事件的回应。我喜欢的一件事是我们有一个主视图呈现了呈现其他子视图的子视图。作为一个约定,我们不直接渲染DOM,但是一旦所有的子视图都被渲染,我们将主视图追加到DOM,整个页面立即显示出来。这可以避免'无格式内容的闪光'

关于引导,我从您阅读FAQ的内容中看到,这正是我在实践中所做的。我使用ASP.Net MVC 3,所以我的服务器端渲染视图将有这样的事情(虽然我不会把对全局命名空间正常的“书”):

<script type="text/javascript"> 
    books = new BooksCollection(); 
    books.reset(@Html.ToJson(Model)); 
</script> 

希望这是有帮助的。

+0

我对Ruby on Rails使用ERB或HAML做同样的事情 –

+0

@timDunham - thanks – UpTheCreek

2

其实,我已经做骨干的一些工作了一小会儿,并且我发现Bootstrapping数据在某些情况下非常有用,当您知道在页面加载时您将需要该数据ASON(t HUS减少额外的AJAX调用)

在Symfony的,我以这种方式呈现所需的数据做到这一点:现在

<script type="text/template" id="__user-boostrap"> 
    {% echo your data from php or render a controller in symfony or whatever server side script/framework you want %} 
    // for example in symfony2, I do: 
    {% render "myBundle:Core:getUser" %} 
</script> 

,在initialize()函数,你可以直接从DOM提起这个数据,并开始做的工作像往常一样:

例如,在我的路由器,我做

myApp.Router = Backbone.Router.extend({ 
    var data = JSON.parse($('__user-bootstrap').html()); 
    var __games = new myApp.Games(); 
    __games.reset(__games.parse(data.games)); 
    var gameList = new myApp.GameListView({ collection: __games }); 
    $(this.gameView).html(gameList.$el); 
}); 

希望这有助于...