requirejs - 使用 requireJS 和预编译的 Handlebars 模板加载翻译 (i18next)

标签 requirejs amd handlebars.js i18next precompiled-templates

我有一个requireJS使用预编译设置 Handlebars模板和我的翻译 i18next在数据库中。我需要按以下顺序做一些事情:

  1. 从数据库加载我的翻译
  2. 在 Handlebars 中注册一个助手,以便可以翻译我的预编译模板中的值

我的 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 将尝试注册 Handlebars 助手并使用翻译初始化 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?

最佳答案

一些注意事项:

  • RequireJS 提供了内置 shim配置属性,您可能不需要 use.js。
  • i18next 提供了 AMD 模块版本(可在其 homepage 上获得),因此您无需对其进行填充。不确定他们是否遵循最佳实践,但它确实有效。
  • 切勿在 AMD 模块中使用全局对象,始终明确要求将对象作为依赖项。
  • 考虑到所有这些,您已经几乎到达了您需要到达的地方;每当您需要在另一个模块中使用其 t 函数时,您只需 require('i18next') 即可。剩下的问题是如何确保 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 的模块之前首先加载和初始化 i18next 的问题。您应该能够对任何其他模块执行相同的操作。

如果您可以使用它,其他人可能可以帮助解决 Handlebars 的具体问题,或者您可以从这里获取它。

编辑:我忘记了 i18next 的异步性质。我记得包装了 t 函数来检查 initialized 标志,以确保 i18next 确实已完全加载(包括翻译)。虽然这有效,但我最终认为增加的复杂性并不会立即值得,并决定改用 getAsync: false i18next 选项。你可能不同意。

关于requirejs - 使用 requireJS 和预编译的 Handlebars 模板加载翻译 (i18next),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20411283/

相关文章:

javascript - 需要js优化器相对路径问题

html - EMBER - 每个处理程序都围绕我的组件生成 ember-view div

javascript - 相对路径不起作用 RequireJS

javascript - 如何使用 SystemJS 指定库依赖项?

javascript - RequireJS 的路径问题

build - Dojo 自定义构建因缺少资源而出现浏览器错误

javascript - Webstorm 代码分析在 Handlebars 模板脚本标记中失败?

node.js - 使用 GET 请求在主页上显示用户信息的最佳实践

jquery - 使用 jquery 从 Promise/ajax 调用返回值

javascript - RequireJS - 无法访问外部模块功能