2

我遇到了一个问题,这可能与我对使用exports/ RequireJS 进行循环依赖缺乏了解有关。

我得到了错误relatedModel does not inherit from Backbone.RelationalModel

关于代码(在 CoffeeScript 中;我希望没问题)......

我有两个主干模型/RequireJS 模块,FooModel 和 BarModel:

Foo型号:

define (require) ->
  Backbone = require 'backbone'
  BarModel = require 'models/bar'

  FooModel = Backbone.RelationalModel.extend
    relations: [
      type: Backbone.HasMany
      key: 'theBars'
      relatedModel: BarModel  # <-- this is where the BB Relational error is coming from
    ]

  return FooModel

酒吧型号:

define (require, exports) ->
  Backbone = require 'backbone'
  FooCollection = require 'collections/foos'

  BarModel = Backbone.RelationalModel.extend
    someFunction: ->
      # uses FooCollection
      # I've tried moving the require in here and getting rid of exports

  exports.BarModel = BarModel
  return BarModel # I've tried with and without this line, but CS just returns the last line anyway so removing it is functionally the same

我也试过:

  1. 扩展FooModelBackbone.Model不是自己Backbone.RelationalModel创建theBars集合(在自定义函数中parse和自定义函数中)。(与另一个模型BarModelHasOne关系,所以我需要它仍然是RelationalModel.

这可能是exports工作方式的问题吗?据我了解,exports只是提供一个对象来挂模块对象,以便模块可以在其他地方访问。发生错误是因为在我定义关系BarModel的代码中实际上不是主干模型吗?FooModel

更新

我似乎已经解决了我的问题,虽然我不确定如何。不能说我很高兴不理解它为什么起作用,但我确实很高兴它起作用了。另请参阅我在代码_.memoize下方的评论。BarModel

(在我让下面的代码工作之前,我创建了一个解决方法,我在FooModelparse函数中创建了关联的集合并导出BarModel了。但是,require 'collections/foos'返回的响应是这样的:{FooCollection: <Backbone.Collection Object>},即它意外地包装在另一个对象中。)

这是更新的代码:

Foo型号:

define (require) ->
  Backbone = require 'backbone'
  BarModel = require 'models/bar'
  BarCollection = require 'collections/bars'

  FooModel = Backbone.RelationalModel.extend
    relations: [
      type: Backbone.HasMany
      key: 'theBars'
      relatedModel: BarModel
      collectionType: BarCollection
    ]

  return FooModel

酒吧型号:

define (require, exports) ->
  Backbone = require 'backbone'

  BarModel = Backbone.RelationalModel.extend
    someFunction: -> #this actually used to use _.memoize (sorry for the incomplete code), so maybe it would have tried to run the function argument immediately? 
      # uses FooCollection
      FooCollection = require 'collections/foos'

  return AttributeModel
4

1 回答 1

0

您的 BarModel 需要'collections/foos',对吗?而且我猜(因为没有代码FooCollection)该集合需要'models/foo',因为集合需要定义它的模型对吗?最后,我可以从上面的代码中看到您的 foo 模型需要 'models/bar'。

换句话说 foos 需要 foo 需要 bar 需要 foos 需要 foo 需要 bar 需要 ...

无论 Require 决定如何订购,都必须先加载这三个中的一个,这会给您带来与您遇到的问题一样的问题。

解决方案是在加载所有三个模块之前不加载这三个模块之一。例如,如果您更改:

define (require, exports) ->
    Backbone = require 'backbone'
    FooCollection = require 'collections/foos'
    BarModel = Backbone.RelationalModel.extend
        someFunction: ->
            # uses FooCollection

至:

define (require, exports) ->
    Backbone = require 'backbone'
    BarModel = Backbone.RelationalModel.extend
        someFunction: ->
            FooCollection = require 'collections/foos'
            # uses FooCollection

现在 BarModel 可以加载了,虽然someFunction定义了,但它实际上还没有运行,所以它不需要 foos 并创建循环依赖。稍后,在加载所有内容并调用一些代码之后someFunction, foos 已经有机会加载,并且 require 应该可以工作。

现在我说应该因为你的评论而工作:

# I've tried moving the require in here and getting rid of exports

同样,我不得不猜测,因为我看不到你的代码,但我想发生的事情是没有其他东西依赖于 foos,所以它永远不会被加载。为了使 foos 的 require 在 内部同步工作someFunction,必须事先加载 foos 模块。

要解决此问题,您只需添加对 foos 的依赖项......只是这次不在任何需要 foos 的模块中(或任何需要需要 foos 的模块,或......)。

希望有帮助。

于 2013-03-16T03:11:48.850 回答