2

循環依存関係に対するexports/ RequireJSの使用に関する理解不足に関係している可能性がある問題に遭遇しました。

エラーが発生していますrelatedModel does not inherit from Backbone.RelationalModel

コードに進みます (CoffeeScript で。問題ないことを願っています)...

FooModel と BarModel の 2 つの Backbone Models / RequireJS モジュールがあります。

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

バーモデル:

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. 自分でコレクションを作成する代わりに拡張FooModelします(カスタム関数内およびカスタム関数内)。(は別のモデルの関係を持っているので、.Backbone.ModelBackbone.RelationalModeltheBarsparseBarModelHasOneRelationalModel

これはおそらくexports動作方法に問題がありますか?私が理解している限り、exportsモジュールオブジェクトをハングアップするためのオブジェクトを提供するだけで、モジュールが他の場所からアクセスできるようになります。コード内でリレーションを定義BarModelした時点で実際にはバックボーン モデルではないため、エラーが発生していますか?FooModel

アップデート

方法はわかりませんが、問題を解決したようです。なぜそれが機能しているのか理解できないことに満足しているとは言えませんが、機能していること確かにうれしいです. _.memoize以下のBarModelコードについての私のコメントも参照してください。

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

バーモデル:

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 がそれをどのように注文しようと決めたとしても、これら 3 つのうちの 1 つを他のものより先にロードする必要があります。

解決策は、3 つのモジュールがすべてロードされるまで、これら 3 つのうちの 1 つをロードしないことです。たとえば、次のように変更するとどうなりますか。

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 に答える