我遇到了一个问题,可能与我缺乏对使用exports
/RequireJS循环依赖关系的理解有关。
我得到错误relatedModel does not inherit from Backbone.RelationalModel
。
在CoffeeScript;
我有两个骨干模型/RequireJS模块,foommodel和BarModel:
FooModel:
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
BarModel:
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
我也试过了:
- 扩展
FooModel
从Backbone.Model
而不是Backbone.RelationalModel
和创建theBars
收集自己(在parse
和自定义功能)。(BarModel
有另一个模型的HasOne
关系,所以我需要它仍然是RelationalModel
。
这可能是exports
工作方式的问题吗?据我所知,exports
只是提供了一个对象来挂模块对象,以便模块可以在其他地方访问。发生错误是因为BarModel
实际上不是在FooModel
代码中定义关系的骨干模型吗?
我似乎已经解决了我的问题,虽然我不确定如何。不能说我很高兴不理解为什么可以工作,但我很高兴可以工作。也可以在BarModel
代码中看到我对_.memoize
的评论。
(在我让下面的代码工作之前,我创建了一个解决方案,我在FooModel
的parse
函数中创建了相关的集合,并导出了BarModel
。然而,require 'collections/foos'
的响应返回了一个像这样的对象:{FooCollection: <Backbone.Collection Object>}
,即它被意外地包装在另一个对象中。
下面是更新后的代码:
FooModel:
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
BarModel:
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
您的BarModel需要'collections/foos'
,正确吗?我猜(因为没有FooCollection
的代码),该集合需要'models/foo'
,因为一个集合需要定义它的模型对吗?最后,我可以从上面的代码中看到,你的foo模型需要'models/bar'。
换句话说,foo需要foo需要bar需要foo需要foo需要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
被定义了,但它还没有实际运行,所以它不需要foo并创建一个循环依赖。稍后,在加载完所有内容并且一些代码调用someFunction
之后,foo已经有机会加载了,并且require应该可以工作了。
现在我说应该工作,因为你的评论:
# I've tried moving the require in here and getting rid of exports
再一次,我不得不猜测,因为我看不到你的代码,但我可以想象发生的事情是没有其他依赖于foo,所以它从未被加载。为了使foos在someFunction
中同步工作,foos模块必须预先加载。
要解决这个问题,你只需要添加对foo的依赖…只是这次不在任何需要foo的模块中(或任何需要需要foo的模块的模块中,或…)。
希望对你有帮助。