主干绑定 AMD 项目中 json 文件中的数据
Backbone bind data from json file in AMD project
我是Backbone的新手,所以我正在尝试一下。我基于这个例子建立了一个模块化项目。我还以与本教程类似的方式实现了页面之间的转换。现在,我被困在 json 文件的一个视图中的数据绑定中。我尝试了很多方法,但没有运气。
这是我的代码:
我有一个"页面管理器",它根据用户的页面处理视图结构以及过渡输入和转换输出功能:
define([
"backbone",
"config-all"
], function(Backbone, Config) {
var pagesManagerView = Backbone.View.extend({
el: $("#page"),
initialize: function(options) {
var $this = this;
this.currentPage = null;
this.backDetected = false;
this.transitionType = "";
this.isFirstPageLoad = false;
this.previousPageMapItem = null;
this.currentPageMapItem = null;
this.pagesMap = {
"home": {
index: 0,
fragment: "",
regex: /^home$/,
pageId: "home"
},
"projects": {
index: 1,
fragment: "projects",
regex: /^projects$/,
pageId: "projects"
},
"users": {
index: 2,
fragment: "users",
regex: /^users$/,
pageId: "users"
}
};
$(document).ready(function(evt) {
});
},
getPageFromMapByFragment: function(fragment) {
if (fragment === "")
fragment = "home";
for (var i in this.pagesMap) {
if (fragment.match(this.pagesMap[i].regex))
return this.pagesMap[i];
}
return this.pagesMap[fragment];
},
updatePageHistoryState: function() {
var currentFragment = Backbone.history.getFragment();
this.currentPageMapItem = this.getPageFromMapByFragment(currentFragment);
this.backDetected =
this.currentPageMapItem &&
this.previousPageMapItem &&
this.currentPageMapItem.index < this.previousPageMapItem.index;
this.transitionType = Config.transitions.PageTransitionType.VERTICAL;
this.isFirstPageLoad = this.previousPageMapItem === null;
this.previousPageMapItem = this.currentPageMapItem;
},
renderPage: function(pageView) {
var $this = this;
this.transitionType = Config.transitions.PageTransitionType.VERTICAL;
if (this.$el.find("#page-out").length === 0)
this.$el.append('<div id="page-out" class="page-out"></div>');
var elIn = this.$el.find("#page-in");
var elOut = this.$el.find("#page-out");
if (this.currentPage) {
var currentPageHtml = elIn.html();
elOut.html(currentPageHtml);
elOut.show();
this.currentPage.$el = elOut;
this.currentPage.transitionOut(this.transitionType, this.backDetected);
}
pageView.$el = elIn;
pageView.render();
pageView.transitionIn(this.isFirstPageLoad, this.transitionType, this.backDetected, function() {
});
this.currentPage = pageView;
return true;
}
});
return pagesManagerView;
});
然后我有一个抽象页面,其中有所有视图共享的函数,包括实际的转换函数:
define(['backbone', 'config-all'],
function(Backbone, Config) {
var abstractPageView = Backbone.View.extend({
render: function() {
},
transitionIn: function(isFirstPageLoad, transitionType, transitionBack, callback) {
switch (transitionType) {
case Config.transitions.PageTransitionType.VERTICAL:
this.transitionInVertical(isFirstPageLoad, transitionBack, callback);
break;
}
},
transitionOut: function(transitionType, transitionBack, callback) {
switch (transitionType) {
case Config.transitions.PageTransitionType.VERTICAL:
this.transitionOutVertical(transitionBack, callback);
break;
}
},
transitionInVertical: function(isFirstPageLoad, transitionBack, callback) {
var $this = this;
var startPosTop = transitionBack
? 0 - $("#page").height()
: 0 + $("#page").height();
if (isFirstPageLoad)
startPosTop = 0;
this.$el.css({
top: startPosTop
});
this.$el.animate({
top: 0
}, {
duration: 500,
easing: "easeOutQuad",
done: function() {
if (callback && typeof callback === "function")
callback();
}
});
},
transitionOutVertical: function(transitionBack, callback) {
var $this = this;
var endPosTop = transitionBack
? $("#page").height()
: -$("#page").height();
this.$el.animate({
top: endPosTop
}, {
duration: 500,
easing: "easeOutQuad",
done: function() {
if (callback && typeof callback === "function")
callback();
// @important remove();
// this must be called upon transition out complete
$this.remove();
}
});
}
});
return abstractPageView;
});
然后有一个观点:
define([
'jquery',
'underscore',
'backbone',
'views/abstract-page',
'views/sidebar/SidebarView',
'text!templates/contributors/contributorsTemplate.html'
], function ($, _, Backbone, AbstractPage, SidebarView, contributorsTemplate) {
var ContributorsView = AbstractPage.extend({
initialize: function () {
},
render: function () {
$('.menu li').removeClass('active');
$('.menu li a[href="' + window.location.hash + '"]').parent().addClass('active');
// render my template
this.$el.html(contributorsTemplate);
// add the sidebar
var sidebarView = new SidebarView();
sidebarView.render();
}
});
return ContributorsView;
});
目前,贡献者模板.html只有静态html,但我想从json文件中绑定一些数据。我对如何使用模型、集合以及如何将数据绑定到模板中感到非常困惑,因为模板是使用 Require 调用的.js并且不知道如何将数据注入div。
这是我的收藏:
define([
'underscore',
'backbone',
'models/contributor/ContributorModel'
], function(_, Backbone, ContributorModel){
var ContributorsCollection = Backbone.Collection.extend({
model: ContributorModel,
url: "js/data/data.json",
initialize: function(models, options) {
}
});
return ContributorsCollection;
});
和模型:
define([
'underscore',
'backbone'
], function(_, Backbone) {
var ContributorModel = Backbone.Model.extend({
defaults : {
}
});
return ContributorModel;
});
和我的 JSON 文件:
[
{
"name": "Google",
"image": "/images/logo.jpg",
"link": "http://www.google.co.uk"
},
{
"name": "Yahoo",
"image": "/images/logo.jpg",
"link": "http://www.yahoo.co.uk"
},
{
"name": "Apple",
"image": "/images/logo.jpg",
"link": "http://www.apple.com"
},
{
"name": "Gizmodo",
"image": "/images/logo.jpg",
"link": "http://www.gizmodo.co.uk"
},
{
"name": "Engadget",
"image": "/images/logo.jpg",
"link": "http://www.engadget.com"
},
{
"name": "9to5 Mac",
"image": "/images/logo.jpg",
"link": "http://www.9to5mac.com"
}
]
在我看来,我真的不明白如何做这样的事情(来自模块化骨干示例(:
// Using Underscore we can compile our template with data
var data = {};
var compiledTemplate = _.template( projectListTemplate, data );
// Append our compiled template to this Views "el"
this.$el.append( compiledTemplate );
我已经尝试过但没有成功,我不明白如何使用data{}
.抱歉,如果问题很长,并且我可能错过了一些Backbone专家可能识别的简单内容。我真的需要一些适合我的代码的示例的帮助,几天来一直在敲打我的头!
提前感谢!
代码更新
试图应用查理布朗的答案但没有运气,我确定我仍然在做一些愚蠢的事情:
收集:
define([
'underscore',
'backbone',
'models/contributor/ContributorModel'
], function(_, Backbone, ContributorModel){
var ContributorsCollection = Backbone.Collection.extend({
model: ContributorModel,
url: "js/data/data.json",
initialize: function(models, options) {
}
});
return ContributorsCollection;
});
视图:
define([
'jquery',
'underscore',
'backbone',
'views/abstract-page',
'views/sidebar/SidebarView',
'collections/contributors/ContributorsCollection',
'text!templates/contributors/contributorsTemplate.html'
], function ($, _, Backbone, AbstractPage, SidebarView, ContributorsCollection, contributorsTemplate) {
var ContributorsView = AbstractPage.extend({
initialize: function () {
},
render: function () {
$('.menu li').removeClass('active');
$('.menu li a[href="' + window.location.hash + '"]').parent().addClass('active');
var contrCollection = new ContributorsCollection();
//compile the template
var data = {items: contrCollection.toJSON() };
var compiledTemplate = _.template(contributorsTemplate, data);
// render my template
this.$el.html(compiledTemplate);
// add the sidebar
var sidebarView = new SidebarView();
sidebarView.render();
}
});
return ContributorsView;
});
模板:
<div class="main" id="contacts">
<h2>Contributors</h2>
<div id="projects-list">
<% _.each(items, function(item) { %>
<%= item.name %>
<%= item.image %>
<%= item.link %>
<% } %>
</div>
</div>
那我做错了什么呢?
再次感谢
答案 2,基于您更新的代码。
您没有显示如何连接事物并使应用程序运行,但我想它在您的主文件中.js(requirejs SCRIPT 标签中的数据主文件(。
很明显,您没有得到任何结果,因为:1. 您要在渲染方法中创建新集合2. 您没有fetch
该集合,因此您的数据永远不会加载!
怀疑你没有读过我推荐给你的文章,因为你正在做的事情是哭泣CollectionView
,但出于学习目的,没关系。 阅读! ;)
var ContributorsView = AbstractPage.extend({
initialize: function (options) {
//Backbone automatically stores options.collection on this.collection
//whenever the collection is reset, re-render this view!
this.listenTo(this.collection, "reset", this.render);
},
render: function () {
$('.menu li').removeClass('active');
$('.menu li a[href="' + window.location.hash + '"]').parent().addClass('active');
//compile the template
var data = {items: this.collection.toJSON() };
var compiledTemplate = _.template(contributorsTemplate, data);
// render my template
this.$el.html(compiledTemplate);
// add the sidebar - WHAT'S THIS?
var sidebarView = new SidebarView();
sidebarView.render();
}
});
现在,无论您在哪里即时显示此视图:
var contrCollection = new ContributorsCollection();
var mainView = new ContributorsView({ collection: contrCollection });
contrCollection.fetch({reset:true}); //we want to trigger the reset event you're waiting for!
明白我的意思吗?从外部为视图提供其集合,或在其initialize
方法中创建。我一点也不喜欢侧边栏视图。您应该从此视图外部创建并呈现它,可能是路由器的路由处理程序。否则,每次render
父视图时,您都将创建另一个将永远保留在内存中的侧边栏视图。http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/
总结:
- 创建集合,创建视图
- 将该集合提供给视图的选项(如果它是在外部创建的(
- 加载数据是异步操作,您应该"等待"数据
- 加载数据后,您可能希望重新呈现视图,以便模板数据具有要显示的内容。
Backbone中的所有内容都与事件相关,因为好事需要时间。 ;)
http://backbonejs.org/#Events-catalog
很复杂,虽然很有趣! :)
好消息 - 你错过的是容易的部分。
您正在使用requirejs文本插件从外部源加载HTML。您只需要使用您选择的模板引擎"编译"该 HTML。您提到的示例使用基本的下划线模板。
不要将 HTML 直接添加到视图的 jQuery 元素中,而是使用您喜欢的数据对其进行编译,然后发送结果:
render: function () {
$('.menu li').removeClass('active');
$('.menu li a[href="' + window.location.hash + '"]').parent().addClass('active');
//compile the template
var data = { text: "Hello world!" };
var compiledTemplate = _.template(contributorsTemplate, data);
// render my template
this.$el.html(compiledTemplate);
}
假设您的模板包含以下内容:
<h1><%= text %></h1>
前面代码的结果是,模板中的text
变量将使用提供给_.template
的上下文进行插值。因此,它将显示">
你好世界!
使用模型和集合时,模板数据通常包含模型数据(如果是集合,则包含模型列表(。
例如,假设您的视图具有如下模型:
this.model = new Backbone.Model({
firstName: "Mauro",
lastName: " Backbone"
});
//compile the template
var data = this.model.toJSON();
var compiledTemplate = _.template(contributorsTemplate, data);
// render my template
this.$el.html(compiledTemplate);
然后,您可以直接将模型属性用作模板文件中的变量:
<h1><%= firstName %> <%= lastName %></h1>
这就是为什么通常你会创建基本的通用View
并从中继承,以避免相同的步骤:
- 序列化模型/集合
- 编译模板
- 输出到视图$el
索梅西格喜欢:
var BaseView = Backbone.View.extend({
render: function(){
if(!this.template) return this;
//abstract data serialization to a method, easy to override in child classes
var data = this.serializeData();
var compiledTemplate = _.template(this.template, data);
this.$el.html(compiledTemplate);
return this;
},
serializeData: function(){
if(this.model){
return this.model.toJSON();
}
else {
return {};
}
}
});
现在定义扩展此视图而不是普通 Backbone.View 的视图,定义模板或模型并渲染。
var ContactView = BaseView.extend({
template: yourRequiredTemplate
});
//in your router or "main app/view"
var contact = new Backbone.Model({
firstName: "Mauro",
age: 20
});
var contactView = new ContactView({
model: contact
});
//for example, let's append it to the body
$("body").append(contactView.render().$el);
希望它有所帮助,您可能想看看 Marionettejs 以查看它提供的专业视图,或者像此示例中一样滚动自己的视图:http://liquidmedia.org/blog/2011/02/backbone-js-part-3/
- Javascript-如何读取json文件中的列并将其保存在Javascript数组中
- 在使用Polymer'加载所有json文件后执行方法;s的核心ajax
- 不显示带有本地json文件数据的谷歌地图脚本
- 可以't使用Appcelerator将JSON文件解析为JavaScript中的TableView
- 加载两个具有相同父密钥名称的json文件
- 使用JSON文件中的变量(字符串)填充文本区域
- 动态显示JSON文件内容
- 正在尝试将JSON文件放入JS数组
- 如何检查Json文件更新,如果更新了,则用更新的数据刷新我的页面
- 单击按钮更改加载到表中的JSON文件
- 处理一个JSON文件;完全相同的副本不是
- 在Javascript中加载JSON文件
- 使用Bootstrap将JSON文件加载到表中
- Angular 2:在本地.json文件上找不到文件
- JSON-从浏览器向外部服务器发送哪些http头JSON文件
- 如何获取d3.js中json文件中具有特定值的总行数
- 如何在dojo应用程序构建概要文件中加载json文件
- jQuery UI使用json文件自动完成
- 通过Azure存储以HTML形式获取JSON文件
- ngResource没有'从JSON文件解析HTML时不起作用