我开始通过实现一个简单的项目来学习Backbone.js库。看了几个教程后,我制作了如下所示的代码。我知道它可能看起来不太完美,因为我是javascript开发的新手。
所以下面,我从API获取国籍列表,然后从这些特定国家获得学生人数。这似乎是暂时的,但问题是,我需要获得每个国籍的学生总数,这就是为什么在第二个集合获取功能中有一个计数器。我面临的问题是关于Javascript。基本上,定义"总计"全局并在本地更新它是我需要做的。我遇到了许多与此类似的线程,但说实话并不能很好地理解我自己的解决方案。再一次,我的问题是如何重新设计这个代码,以便我可以更新变量的值" total"在本地,然后使用内部提取功能之外的更新结果。我感谢您的回答和建议。提前谢谢。
$.ajaxSetup({
crossDomain : true,
cache : false,
contentType : "application/json",
dataType : "json"
});
var baseURL = "http://lucalongo.eu:80/courses/2014-2015/questionnaireDIT/app/index.php";
var mModel = Backbone.Model.extend({});
var cNationality = Backbone.Collection.extend({
model: mModel,
url: this.baseURL + "/nationalities"
});
var cStudent = Backbone.Collection.extend({
model : mModel,
initialize : function(models, options) {
this.url = "http://lucalongo.eu:80/courses/2014-2015/questionnaireDIT/app/index.php/students/nationality/" + options.id;
}
});
var vView = Backbone.View.extend({
render: function(){
var total = 0;
this.collection = new cNationality();
this.collection.fetch({
success: function(c){
_.each(c.models, function(col) {
var nationalDesc = col.toJSON().description;
var nationalID = col.toJSON().id;
var studentNationality = new cStudent([], {id : nationalID});
studentNationality.fetch({
success: function(c){
//console.log(nationalDesc + ": " + c.length);
total = total + c.length;
console.log(total);
}
});
});
}
});
console.log("Total:" total); // still displays 0
}
});
var v = new vView();
v.render();
Backbone.history.start({pushState: true});
答案 0 :(得分:1)
Backbone尝试推广事件驱动的方法 我认为你最终会得到一个事件聚合器;
window.APP = {};
APP.vent = _.extend({}, Backbone.Events);
APP.vent.on("update:counter", function(increment){
APP.counter = APP.counter + increment;
});
从调用代码中触发事件:
var increment = 5 //Just an example
APP.vent.trigger("update:counter", increment);
答案 1 :(得分:1)
尝试使用:{async: false}
// Ajax-JQuery: Perform an asynchronous HTTP (Ajax) request
this.collection.fetch({async: false}, {
success: function(c) {
_.each(c.models, function(col) {
var nationalDesc = col.toJSON().description;
var nationalID = col.toJSON().id;
var studentNationality = new cStudent([], {
id: nationalID
});
studentNationality.fetch({
success: function(c) {
//console.log(nationalDesc + ": " + c.length);
total = total + c.length;
console.log(total);
}
});
});
}
});
可能对您有帮助的链接:Backbone.Sync
让我知道它是否有效。
答案 2 :(得分:0)
检查控制台输出,如果AJAX调用按设计工作,您应该看到Total:0
优先然后是预期值。这是按设计工作的,因为在函数调用fetch
完成后,fetch选项中的回调函数将被称为。
根据您的设计,您不需要全局变量total
,因为主干集合支持.length
约定。请参阅http://backbonejs.org/#Collection-length当您的提取功能完成时。见http://backbonejs.org/#Collection-fetch
答案 3 :(得分:0)
我认为您正在寻找的是一种在视图中的任何位置操纵total
的方法。我倾向于做什么,如果我想要一个变量是"全球"我所有的视图方法都是使它成为视图的属性。我所说的是,
var vView = Backbone.View.extend({
initalize: function(){
// Initialize your object property
this.totalCount = 0;
},
render: function() {
// Inside callbacks you will lose your view context
// so save it
var that = this;
// Nested collection fetch
success: function(c){
that.totalCount = that.totalCount + c.length;
console.log(that.totalCount);
}
// rest of code
}
});
由于collection fetch是ajax GET的包装器(除非你覆盖Backbone.sync
),它将异步运行。如果你想与fetch同步运行代码,你可以做三件事。
@KimGysen
所说的内容:Backbone具有用于设置和响应事件的可靠API。 (Marionettejs在非常酷的方向扩展了这个API)。