5

У меня есть установка requireJS с предварительно скомпилированными шаблонами Handlebars и моими переводами i18next в базе данных. Мне нужно сделать несколько вещей, в следующем порядке:Загрузите переводы (i18next) с помощью requireJS и предварительно скомпилированных шаблонов Handlebars

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

Мои requireJS конфигурационный файл выглядит следующим образом:

require.config({ 
    deps: ["main"], 
    paths: { 
    'handlebars.runtime': "../assets/js/libs/handlebars.runtime.amd.min", 
    i18n: "../assets/js/libs/i18next-1.7.1", 

    // Shim Plugin 
    use: "../assets/js/plugins/use" 
    }, 

    use: { 
    i18n: { 
     attach: "i18n" 
    } 
    } 
}); 

Мой main.js файл выглядит так, что требует namespace.js:

require([ 
    'namespace', 
    'modules/Transport' 
], function (
    namespace, 
    $, 
    Transport 
) { 
    var Router = Backbone.Router.extend({ 
    routes: { 
     '*any':    'any' 
    }, 

Мой namespace.js попытается зарегистрировать помощник Рулей и инициализировать i18next с переводами:

define([ 
    "handlebars.runtime", 
    "use!i18n" 
], function(
    Handlebars, 
    i18n 
) { 
    var defaultLanguage = 'en'; 
    var translations; 
    $.when(
     $.getJSON('/api/translations', function (result) { 
     translations = result; 
     }) 
).then(function() { 

    i18n.init({ useCookie: false, resStore: translations, lng: defaultLanguage }); 

    Handlebars.default.registerHelper('t', function(i18n_key) { 
     var result = i18n.t(i18n_key); 

     return new Handlebars.default.SafeString(result); 
    }); 
    }); 

Моего modules/Transport.js модуль, будет зависеть от namespace.js и загрузит прекомпилированный шаблон. При загрузке предварительно скомпилированного шаблона он становится доступным в Handlebars.default.templates. Так что мой модуль выглядит следующим образом:

define([ 
    'namespace', 
    'templates/compiled/transport_template' 
], function(
    namespace, 
) { 
    i18n.t('translate something'); 
    var template = Handlebars.default.templates['transport_template']; 

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

Я действительно смущен здесь, как можно Я устанавливаю requireJS для загрузки Handlebars и i18next, прежде чем загружать модули?

ответ

4

Несколько примечаний:

  • RequireJS обеспечивает встроенный shim свойства конфигурации, вам может не понадобиться use.js.
  • i18next предоставляет версию модуля AMD (доступна на их homepage), поэтому вам не нужно ее подгонять. Не уверен, что они следуют лучшим практикам, но это работает.
  • Никогда не используйте глобальные объекты в модуле AMD, всегда требуйте объекты как зависимости явно.
  • Учитывая все это, вы уже почти находитесь там, где вам нужно быть; вы просто require('i18next') всякий раз, когда вам нужно использовать его функцию t в другом модуле. Остальной проблемой является вопрос о том, как обеспечить правильную инициализацию i18next, для которой я даю ответ ниже.
  • Я не знаком с Handlebars и особенно с его помощниками, поэтому это может быть ответом на половину ваших проблем.

Мне пришлось решить по существу ту же проблему с i18next некоторое время назад; Я в основном завернул его модуль в другом модуле, который инициализирует i18next перед его возвратом.

i18next-wrapper.JS

define(function (require) { 
    var i18next = require('i18next-actual'); 
    i18next.init(...); 
    return i18next; 
}); 

Для обеспечения дополнительной прозрачности, вы можете играть с путями:

requirejs.config({ 
    paths: { 
     'i18next-actual': 'path/to/i18next.amd-$version', 
     'i18next': 'path/to/i18next-wrapper', 
    } 
}); 

Таким образом, все модули пользователей, которые require('i18next') как обычно будет уверен, что она инициализируется раз и фактический модуль i18next не нужно изменять.

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

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

Редактировать: Я забыл об асинхронной природе i18next. Я помню, как обертывал функцию t, чтобы проверить флаг initialized, чтобы убедиться, что i18next действительно загружен (включая переводы). В то время как это сработало, я в конечном счете полагал, что добавленная сложность не сразу стоила того и решила использовать опцию getAsync: false i18next. Вы можете не согласиться.