@xaseros

Как подключать встречные зависимости RequireJS?

Есть 2 сущьности Task (Задание) и Stage (Этам). Соответственно они выраженны 2-мя моделями backbone.

В проекте для подгрузки моделей используется RequireJS. Модели объявляются так.

define('model/stage', [
    'common/model',
    'model/task'
], function(
    Common,
    Task
){
    var Stage = {};
    
    Stage.Model = Common.Model.extend({
        
    });
    
    Stage.Collection = Common.Collection.extend({
        url: function(){
            return this.task.url() + "/stages";
        },
        task: null,
        initialize: function(models, options){
            if(!options || !options.task || ! (options.task instanceof Task.Model)){
                throw "Task model must be set";
            }
            this.task = options.task;
        }
    });
    
    return Stage;
});


и
define('model/task', [
    'common/model',
    'model/stage'
],
function(
    Common,
    Stage
){
    
    var Task = {};
    
    Task.Model = Common.Model.extend({
        setters:{
            stages: function(value, options){
                return (this.get('stages') && this.get('stages').set(value)) || (new Stage.Collection(value, {task:this}));
            }
        }
    });
    
    Task.Collection = Common.Collection.extend({
        url: UnitteCfg.restUrl+"/tasks",
        model:Task.Model
    });
    
    return Task;

});


из кода как видите что оба компонента имеют встречные зависимости. Task хранит в себе в качестве атрибута коллекцию Stage, а для Stage важно получить экземпляр Task что бы проверить выставлен ли именно он.

Task загружается первой, так как указанна в качестве зависимости у другого компонента. Однако при загрузке Stage, то что попадает в в замыкание переданное третьим аргументом require? почему то является undefined

define('model/stage', [
    'common/model',
    'model/task'
], function(
    Common,
    Task   // <- вот это почему-то undefined
){
. . .


ну и соответственно на Stage ошибка, то что Task.Model не существует.

В принципе оно и понятно, ведь когда Require собирает зависимости, она совершенно не знает о том, что будет в этих компонентах, и само собой, не может передать компонент который сам еще не инициализировался в другой компонент, который его запросил.

Но как быть в такой ситуации?
  • Вопрос задан
  • 258 просмотров
Решения вопроса 1
@xaseros Автор вопроса
Если кому надо то вот дока

requirejs.org/docs/api.html#circular

Или решение для конкретного случая, когда Task требуется на этапе выполнения, а не на этапе декларирования состоит в том, чтобы объявить в замыкании имя Task, а запись в него элемента нужного компонента доверить той-же require

define('model/stage', [
    'common/model'
], function(
    Common
){
    
    var Stage = {};
    
    var Task; // объявляем имя в замыкании
    
    require(['model/task'],function(module){ // просим загрузить нам указанный модуль, когда появится возможность
        Task = module;  // записываем в объявленное имя наш полученный модуль, но само собой, нет гарантии когда это произойдет
    });

. . .
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы