我面临的一个问题是Backbone似乎是为了你加载你的javascript,然后让它请求数据(通常是JSON)到服务器,然后它呈现视图。在我的情况下,这是不可接受的。我想把html源于服务器,将它呈现给用户,然后使用那个html填充我的模型(之后,我对从服务器请求JSON内容的模型很好)。
我猜我需要的是某种“逆视图”。给出这个html的东西:
<ul class="people">
<li><span class="name">Peter</span></li>
<li><span class="name">John</span></li>
</ul>
People Collection和具有name属性的Person模型可以解析Peter和John(可能使用View)。
这是存在的吗?我是以错误的方式接近整个事情吗?
答案 0 :(得分:5)
可以将Backbone.View
附加到服务器上预先呈现的HTML页面。我在this SO answer中更详细地描述了这一点。这是page needs to be crawlable by search engines。
但是,我建议您不要通过解析服务器呈现的HTML来初始化模型状态。我建议您将bootstrap初始模型数据作为JSON提供给服务页面。类似的东西:
<body>
<!-- your server-side template code here -->
<script>
window.bootstrap = {
people: <%= @people.to_json %>
};
</script>
</body>
初始化集合时,您只需从引导数据中初始化它们并丢弃引导的集合:
var bootstrap = window.bootstrap || {};
var peopleCollection = new PeopleCollection(bootstrap.people);
delete window.bootstrap;
确保您的服务器端呈现引擎使用与引导相同的数据,因此您可以保证呈现的页面和初始模型数据同步。
或者,重新考虑像Backbone这样的框架是否适合您的需求。你说你的应用程序有很少的(javascript)功能。你需要Backbone吗?这是一个很棒的框架,但你想要的是适合工作的正确工具。
答案 1 :(得分:3)
我最后只是在每个视图的元素上添加了我需要的每个模型的json。
换句话说:
<ul class="people" data-collection="people">
<li data-model="person" data-attributes='{"name":"Peter"}'>Peter</li>
<li data-model="person" data-attributes='{"name":"John"}'>John</li>
</ul>
在我的案例中,每个属性上的JSON片段都很容易在服务器上生成。
我更喜欢在html中嵌入json而不是在开头的大数组中返回它的原因是这样我可以很容易地将模型附加到他们的视图中。
其余来自那里。
我使用jquery来检测data-collections
并创建与DOM元素相关联的相应视图。然后我解析模型,最后我开始在集合视图上听取事件。
$(function(){
$('[data-collection="people"]').each(function() {
var view = new PeopleView({el: this});
view.parse();
view.listen();
});
});
parse
和listen
方法如下所示:
MyApp.PeopleView = Backbone.View.extend({
collection: MyApp.Collections.People,
...
parse: function() {
var people = this.$("[data-model='person']").map(function(i,el){
return new MyApp.Models.Person($(el).data('attributes'));
};
this.collection.reset(comments, {silent: true});
},
listen: function() {
this.listenTo(this.collection, 'add', this.showNewPerson, this);
this.listenTo(this.collection, 'reset', this.renderEveryone, this);
this.delegateEvents();
}
...
});
在这个特殊情况下,我不需要为列表中的每个人创建特定的Backbone视图。但如果我需要,我可以在parse
方法中这样做。
答案 2 :(得分:1)
您可以使用服务器或客户端代码预呈现HTML。虽然我不确定为什么在你的情况下必须通过AJAX加载HTML。无论如何,Backbone Model
或Collection
在您对其进行提取之前并不真正了解其定义。
最重要的是,您可以预加载预定义的View
并使用Backbone进行更改。在您的情况下,如果您希望Backbone在$('.people')
上运行,您只需在添加新记录之前添加新行或清空元素即可。
至于从呈现的Models
解析您的实际View
,不确定为什么要这样做,但您可以使用jQuery
遍历它并选择html()
或{ {1}}。
如果您可以执行text()
请求,我不明白为什么发送实际的AJAX
会有问题。
Model
Backbone对使用和主要结构基础没有任何限制。希望这能解决你的问题。
答案 3 :(得分:1)
我正在使用Backbone LayoutManager来执行此操作。您可以定义一个fetch()函数,其中可以远程获取视图(即您的服务器)。然后将它们缓存在Javascript模板对象中。
部分代码来自Backbone BoilerPlate:
var app = { root: "/" };
var JST = window.JST = window.JST || {};
// Configure LayoutManager
Backbone.LayoutManager.configure({
....
fetch: function(path) {
var done;
path = path + ".html";
if (!JST[path]) {
done = this.async();
$.ajax({ url: app.root + path }).then(function(contents) {
JST[path] = _.template(contents);
done(JST[path]);
});
}
return JST[path];
}
});