Backbone集合不是构造函数

时间:2016-11-15 17:38:02

标签: backbone.js collections requirejs

我已经检查过那些显然存在相同问题的人的答案,但我还没有解决我的问题。

我有一个视图(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

enter image description here

1 个答案:

答案 0 :(得分:0)

好的,我的第一个猜测是从未调用levelModel上的parse方法。但应始终在fetched上调用它。此外,我重读了你的问题,看到有时它确实对你有用。

所以我现在的第二个猜测是带有race condition的{​​{1}}。即:有时在requirejs内,SubjectCollection是一个真实的levels.js,有时是未定义的。

此类Backbone Collection的原因之一可能是Circular Dependencies。你能分享完整的消息来源吗?或者确认你没有这样的race