9

Чтение документации requireJs,
для исправления круговых зависимостей, предлагается использовать exports для создания пустого объекта для модуля, который доступен для немедленной ссылки другими модулями.Циркулярные зависимости в модулях с использованием requireJs

Прошу этот код, но, похоже, не работает. Что не так?

P.S .:
прочитать комментарии для просмотра выход,
особенно модуль B внутри SetTimeout вызова.


// A module 
define([ 
    'b' 
], function (b) { 
    console.log('B:', b); // B, Object 
    var A = { 
     boo: 1 
    }; 

    return A; 
}); 

// B module 
define([ 
    'a', 
    'exports' 
], function (a, exports) { 
    console.log('A:', a); // A, undefined (as I was expecting) 
    exports.A = function() { 
     return a; 
    } 

    var B = { 
     bar: 1 
    }; 

    setTimeout(function() { 
     console.log('exports.A', exports.A()); // exports.A undefined 
              // I would like to access the A object 
              // which is defined in A module 
    }, 500); 

    return B; 
}); 

// main.js 

(function() { 

    define([ 
     'a' 
    ], function() { 
    }); 
}()); 
+0

Я думаю, что это может быть полезно http://stackoverflow.com/questions/4771025/understanding-when-and-how-to-use-require-js?rq=1 – Jake

+0

@ lorraine-bernand Вы выяснили, как решать это? Ссылка выше не дает мне достаточно ручек для ее решения. – donnut

+0

Жаль, что это был ответный вопрос. Я сталкиваюсь с этим все время :) – SimplGy

ответ

0

Я часто имеют круговые проблемы с использованием модулей AMD построить ядро ​​приложения, как ратует множество модулей и содержит конфигурационные или другие полезные объекты для тех, модули для использования.

Я действительно экспериментировал сегодня, и это, похоже, работает очень хорошо.

define(['exports', 'underscore', './config', './mediator'], 
    function (exports, _, Backbone, config, Mediator){ 

    Core = /* ... */ 

    // Publicize a core 'singleton' so that it's dependencies can access it, and so can modules that define it as a dependency themselves. 
    core = new Core() 
    exports.core = core //publicize it in a way that supports circularity 
    return core // And also publicize it normally 
    } 
) 

Объекты оба «===» равны друг другу, поэтому это кажется очень перспективным.

РЕДАКТИРОВАТЬ:

Описанный выше метод не работает, когда оптимизирован. Вот еще один метод, который может (непроверенные): https://github.com/requirejs/example-multipage/blob/master/www/js/app/main1.js#L2

define(function (require) { 
    var $ = require('jquery'), 
     lib = require('./lib'), 
     Core; 

    Core = /* ... */ 

    return new Core() 
}); 
+0

На самом деле, я бы не использовал этот метод. Он работает для неоптимизированного кода, но если вы запустите оптимизатор, то ваш экспорт недоступен, выглядит. – SimplGy

+0

Я сейчас занимаюсь этой проблемой круговых зависимостей, поэтому мне интересно, есть ли у вас предлагаемая альтернатива –

+0

К сожалению, нет. Это был вопрос в течение года или около того, я использовал RequireJS и CurlJS для управления модулем приложений. Мое «решение» - передать ссылку на объект посредника на все, от чего зависит посредник, и начать новую цепочку зависимостей на уровне «страницы». Это выглядит примерно так: https://github.com/SimpleAsCouldBe/appCore/blob/master/shared/appCore/app.js#L45 Это не здорово. Я хочу быть в состоянии всегда получать свои зависимости через декларацию :( – SimplGy

0

Одним из вариантов было бы не возвращать сам модуль, но функция, которая создает экземпляр модуля (в данном примере это будет конструктор, как это определено в машинописи, в нижней части это сгенерированный код JS -ПРИМЕЧАНИЕ, что интерфейсы не генерировать .js код)

  • Файл IA.ts

    /// <reference path="IB.ts" /> 
    interface IA{ 
        funcA(); 
        _classB : IB; 
    } 
    
  • Файл IB.ts

    /// <reference path="IA.ts" /> 
    interface IB{ 
        funcB(); 
        _classA : IA; 
    } 
    
  • Файл ClassA.ts

    /// <reference path="IA.ts" /> 
    /// <reference path="IB.ts" /> 
    
    export class ClassA implements IA 
    { 
        _classB : IB = null; 
    
        constructor(classB : IB) 
        { 
         this._classB = classB; 
         if (classB){ 
          this._classB._classA = this; 
         } 
         return this; 
        } 
    
        funcA(){ 
         console.log('I am ClassA'); 
        } 
    } 
    
  • ClassB.ts Файл

    /// <reference path="IA.ts" /> 
    /// <reference path="IB.ts" /> 
    export class ClassB implements IB 
    { 
        _classA : IA = null; 
        constructor(classA : IA) 
        { 
         this._classA = classA; 
         if (classA){ 
          this._classA._classB = this; 
         } 
         return this; 
        } 
        funcB(){ 
         console.log('I am ClassB'); 
        } 
    } 
    
  • Файл MainTest.ts

    /// <reference path="../../def/require.d.ts" /> 
    /// <reference path="IA.ts" /> 
    /// <reference path="IB.ts" /> 
    define(['ClassA', 'ClassB'], 
        function (classA, classB) 
        { 
         var aa : IA = new classA.ClassA(); 
         var bb : IB = new classB.ClassB(aa); 
    
         bb.funcB(); 
         aa._classB.funcB(); 
         bb._classA.funcA(); 
         aa.funcA(); 
        }); 
    

И сгенерированный JS код:

  • Файл ClassA.JS

    define(["require", "exports"], function(require, exports) { 
        var ClassA = (function() { 
         function ClassA(classB) { 
          this._classB = null; 
          this._classB = classB; 
          if (classB) { 
           this._classB._classA = this; 
          } 
          return this; 
         } 
         ClassA.prototype.funcA = function() { 
          console.log('I am ClassA'); 
         }; 
         return ClassA; 
        })(); 
        exports.ClassA = ClassA; 
    }); 
    
  • ClassB.js Файл

    define(["require", "exports"], function(require, exports) { 
        var ClassB = (function() { 
         function ClassB(classA) { 
          this._classA = null; 
          this._classA = classA; 
          if (classA) { 
           this._classA._classB = this; 
          } 
          return this; 
         } 
         ClassB.prototype.funcB = function() { 
          console.log('I am ClassB'); 
         }; 
         return ClassB; 
        })(); 
        exports.ClassB = ClassB; 
    }); 
    
  • Файл MainTest.js

    define(['ClassA', 'ClassB'], function (classA, classB) { 
    
        var aa = new classA.ClassA(); 
        var bb = new classB.ClassB(aa); 
    
        bb.funcB(); 
        aa._classB.funcB(); 
        bb._classA.funcA(); 
        aa.funcA(); 
    
    }); 
    

наконец, выход будет:

Я ClassB

Я ClassB

Я ClassA

Я ClassA

1

Вы должны быть в состоянии использовать синхронную версию require() в модуле B, чтобы получить доступ к модулю «A»:

// B module 
define([ 
    'a', 
    'exports' 
], function (a, exports) { 
    console.log('A:', a); // A, undefined (as I was expecting) 
    exports.A = function() { 
     return require('a'); 
    } 
    ... 
}); 
Смежные вопросы