durandal activators - как создать модуль, который реализует activ () при его загрузке или первом использовании

Прочитав документацию по активаторам, я все еще не понимаю, как использовать активаторы. То, что я пытаюсь сделать, просто:

Я определил модуль requireJS под названием global. Когда я использую этот модуль в других модулях, его функция активации не вызывается. Мне нужно это быть.

Если я загружаю модуль с помощью compose:, активировать функции fire просто отлично. Но если я просто загружаю его как модуль AMD, это не так. Это все, что я хочу исправить.

Примечание: мой модуль одноэлементный, и мне нужно активировать только один раз, чтобы запустить его, поэтому я попробовал что-то вроде этого, что не работает, мой shell.js

define(['plugins/router', 'durandal/app', 'plugins/ajax','durandal/global'], function (router, app,ajax,global) {

    var vm = {};

    vm.global = global;

    vm.activate= function () {
        return vm.rebuildRouter();

//not sure what this does, does it return a promise, does it run global's activate, does it hook up global so it activates at a later time, and if so when?
        global.activator.activateItem(global); //I created an activator and called in activator inside global. Since its a singlton I think I only need one?

//Since I wasn't sure how to use activators I had to do this instead:
    var promise = global.activate();
        return promise;

//which works only the first time 
    }

Буду признателен, если кто-нибудь сможет объяснить мне этот активаторский бизнес. Я использую активировать все время с compose, и это работает так, как я хочу. Я просто не понимаю, что мне нужно сделать, чтобы заставить его работать, как описано выше, и не могу найти простой пример, который показывает, как заставить любой модуль js вести себя так же.

3 ответа

Решение

Активатор - это специальный вычисляемый объект, функция записи которого обеспечивает жизненный цикл активации, когда его значение пытается изменить.

Жизненный цикл активации

  1. canDeactivate вызывается по текущей стоимости
  2. canActivate вызывается на значение пытается установить
  3. deactivate вызывается по текущей стоимости
  4. activate вызывается на значение пытается установить

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

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

К сожалению, RequireJS не предоставляет (как мне известно) способ ожидания выполнения модулем асинхронной работы.

Вот одна вещь, которую вы могли бы сделать. С Дюрандала app.start инициализация является асинхронным процессом, вы можете подключиться к нему так, чтобы ваш вызов setRoot идет после global инициализировал.

Глобальный файл

define(['durandal/app', 'plugins/ajax', 'durandal/global'], function (app,ajax) {
    return function GlobalModule() {
        activate: function() {
            return //some promise;
        }
    };
});

Main.js

define(['durandal/system', 'durandal/app', 'durandal/global'],
function (system, app, global) {
    app.configurePlugins({ /* plugins */ });

    app.title = 'App';
    app.start()
        .then(global.activate)
        .then(function () {
            app.setRoot('shell');
        });
});

Это обеспечит setRoot не начинается до global закончил активацию. Тогда в любом коде вашего приложения должно быть безопасно его использовать.

Пожалуйста, имейте в виду, я понятия не имею, что durandal/global есть, и эта работа зависит от activate быть функцией возврата обещания.

У вас есть много неверных предположений в вашем вопросе... Вы смешиваете разрешение модуля AMD (сделанное с помощью require.js) и рассматриваете композицию (концепция дюрандала), как будто это одно и то же.

В любом случае, я думаю, что вы идете по неверному пути с активаторами (так как они являются отдельной концепцией от простого разрешения модулей AMD), поэтому я собираюсь обойти реальный вопрос и ответить на вопрос, который, по моему мнению, должен быть, который это: Как я могу добавить логику автоматической инициализации в модуль AMD?

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

В любом случае, я не могу представить себе лучшего места для реализации логики инициализации, чем в функции конструктора модуля.

По сути, вы хотите реализовать свой модуль AMD как функцию конструктора, поместить туда свою логику инициализации и использовать одноэлементный шаблон, чтобы логика инициализации происходила только один раз.

Это может быть полезным ресурсом для вас:

http://unscriptable.com/2011/09/22/amd-module-patterns-singleton/

Извиняюсь, если я не прочитал, что вы пытаетесь сделать здесь.

В конце концов я выполнил то, что мне было нужно, но это лучший способ и / или как это должно быть сделано? Я думаю, что это не идеально, потому что мне нужен весь этот код в каждом модуле, для каждого модуля, который я включаю:

var viewModel = {}; viewModel.global = activator.create ();

viewModel.activate = function () {

    return $.when(viewModel.global.activateItem(global),
               ... other ajax calls and stuff
               ))
               .then(function () {
                    //stuff I used to have in my activate function before, that needs global to already exist
               });
};

Это действительно как правильно использовать активатор? То, что у меня есть выше, работает, но, как кто-то указал, я мог бы просто вызвать global.activate() вместо activItem(global), и мне вообще не понадобился бы активатор... так, какова цель этого?

Когда вы что-то сочиняете, жизненный цикл активации происходит сам по себе. Я пытаюсь создать модуль, который также имеет жизненный цикл, даже если я его не пишу, возможно ли это?

Другие вопросы по тегам