我已经检查过那些显然存在相同问题的人的答案,但我还没有解决我的问题。
我有一个视图(teacher.profile.js
)正在调用一个集合(levels.js
),它有一个集合(subject.js
),但是当我加载页面时,主题集合总是{ {1}}并且说不是构造函数。
经过多次刷新,有时是第二次,undefined
集合就在那里并且有效。
有人能告诉我出了什么问题吗?
由于
subject.js
subject
subjects.js
define(["GB"], function(GB) {
var subjectModel = GB.Model.extend({
idAttribute:"subjectId",
defaults: {
subjectId: '',
name: '',
levelId: '',
selected: false
}
});
return subjectModel;
});
level.js
define([
"GB",
"modules/register/teacher/models/subject"],
function (GB, SubjectModel) {
var subjectCollection = GB.Collection.extend({
model: SubjectModel,
url: "webapi/api/Administration/Subject"
});
return subjectCollection;
});
levels.js
define(['GB', 'modules/register/teacher/models/subjects'], function (GB, SubjectCollection) {
var levelModel = GB.Model.extend({
defaults: {
levelId: '',
name: '',
iconClass: '',
subjects: ''
},
parse: function(attrs) {
**attrs.subjects = new SubjectCollection(attrs.subjects);** //Here is where the error is thrown. SubjectCollection is not a constructor.
return attrs;
}
});
return levelModel;
});
teacher.profile.js 查看
define(["GB", "modules/register/teacher/models/level"], function (GB, LevelModel) {
var levelCollection = GB.Collection.extend({
model: LevelModel,
url: "webapi/api/Administration/Level"
});
return levelCollection;
});
main.js
define([
"GB",
"tpl!modules/register/teacher/teacherProfile", "modules/register/teacher/subject.level"
], function(GB, Template, SubjectLevelView) {
var view = GB.Views.Item.extend({
template: Template,
ui: {
subjects: "#subject-list",
levels: "#level-list",
infoTitle: "#info-title",
subjectsLevels: "#subjects-levels"
},
initialize: function() {
this.userLevels = [];
},
onRender: function() {
var self = this;
this.ui.infoTitle.text(GB.Localise("teacher-data-title"));
var levelsPromise = this.collection.fetch();
$.when(levelsPromise)
.then(function() {
var levelsSubjects = _.map(self.collection.models, function(item) {
if (item.get("subjects").length > 0) {
var view = new SubjectLevelView({ model: item });
self.userLevels.push(item);
return view.render().el;
}
});
self.ui.subjectsLevels.append(levelsSubjects);
});
}
});
return view;
});
app.js
require.config({
map: {
'*': {
'css': 'plugins/require-css/css',
'tpl': 'plugins/require.lodash.template', //this is our templating helper tpl!.html, its brings the template in already underscored, this is faster slightly than text! & subsequent template
'lodash': 'underscore'
}
},
paths: {
'plugins': '../plugins',
'styles':'../css',
'localisation':'core/localisation',
'jquery': '../lib/jquery-2.1.4',
'jquery.browser': '../plugins/jquery.browser',
'jquery.video': '../plugins/vide/jquery.vide',
'waypoints': '../plugins/waypoints/jquery.waypoints',
'backbone': '../lib/backbone',
'marionette': '../lib/backbone.marionette',
'text': '../lib/text',
'underscore': '../lib/lodash.underscore', //yes underscore is now lodash - its a better performer + extra features + no downside :)
'lodash': '../lib/lodash.underscore',
'bootstrap': '../lib/bootstrap',
'bootstrap-dialog': '../plugins/bootstrap-dialog/js/bootstrap-dialog',
'modernizr': '../lib/modernizr-2.8.3',
'backbone.validation': '../plugins/backbone-validation',
'themepunch.tools': '../plugins/rs-plugin/js/jquery.themepunch.tools.min',
'themepunch.rev': '../plugins/rs-plugin/js/jquery.themepunch.revolution.min',
'smoothscroll': '../plugins/SmoothScroll',
'json': '../plugins/requirejs-plugins/json',
'cldr': '../plugins/localisation/cldrjs/cldr',
'cldr-data': '../plugins/localisation/cldr-data',
'globalize': '../plugins/localisation/globalize/globalize',
'localise':'localisation/localise',
'GB': 'app'
},
shim: {
'marionette': {
deps: ['backbone'],
exports: 'Marionette'
},
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'backbone.validation': {
deps: ['backbone', 'underscore']
},
'bootstrap': {
deps: ['jquery'],
},
'bootstrap-dialog': {
deps: ['bootstrap'],
},
'smoothscroll': {
deps: ['jquery.browser']
},
'themepunch.tools': {
deps: ['jquery']
},
'themepunch.rev': {
deps: ['themepunch.tools']
},
'jquery.browser': {
deps: ['jquery']
},
'waypoints': {
deps: ['jquery']
},
'jquery.video': {
deps: ['jquery']
},
'globalize': {
deps: ['cldr']
},
'json': {
deps: ['text']
}
}
});
require([
"GB",
"routes/application.router",
"bootstrap",
"core/validation"],
function (GB, AppRouter) {
GB.routers.application = new AppRouter();
GB.start();
});
Foder Structure
答案 0 :(得分:0)
好的,我的第一个猜测是从未调用levelModel上的parse
方法。但应始终在fetched
上调用它。此外,我重读了你的问题,看到有时它确实对你有用。
所以我现在的第二个猜测是带有race condition
的{{1}}。即:有时在requirejs
内,SubjectCollection是一个真实的levels.js
,有时是未定义的。
此类Backbone Collection
的原因之一可能是Circular Dependencies
。你能分享完整的消息来源吗?或者确认你没有这样的race
?