Подтвердить что ты не робот

Ember: динамический переключатель на выбранный язык (с использованием библиотеки i18n)

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

См. http://jsfiddle.net/cyclomarc/RYbNG/7/

При запуске приложения он отображается на английском языке. Теперь вы можете выбрать один из видов (О программе или Инфо), и они также отображаются на английском языке. Когда вы нажимаете "Голландский", словарь голландского языка загружается и приложение перенаправляется на индексный маршрут на правильном языке.

Кажется, что новые языковые строки используются только при переходе на фиктивный маршрут, а затем обратно на нужный маршрут (в моем примере это всегда "индекс" ).

updateLanguage: function (lang) {
    var _self = this;
    //Load correct dictionary and transition to index route
    $.getScript("http://libraries.azurewebsites.net/locales/dictionary_" + lang + ".js", function () {
      CLDR.defaultLanguage = lang;
      _self.transitionToRoute('I18redirect');
    });
  }

App.I18redirectRoute = Ember.Route.extend({
  activate: function () {
    this.transitionTo('index');
  }
});

Мои вопросы:

  • Это лучший способ перезагрузить view.template(переход на фиктивный маршрут, а затем активировать переход к индексу)?

  • Есть ли способ перехода на маршрут, где вы запросили изменение языка (нужно было бы что-то использовать с get (path) или так)?

  • Я также хотел бы перевести строки "снаружи" в красный div (выход приложения). Я возвращаюсь к индексу, но в этом случае шаблон приложения не перерисовывается... В чем причина?

  • Ожидается ли, что когда вы удаляетесь от шаблона и затем повторно вводите шаблон, сам шаблон перестраивается со всеми языковыми строками или это происходит только тогда, когда в то же время язык изменяется? Как можно перерисовать шаблон с новыми строками в журнале консоли?

Любые другие идеи, чтобы сделать это надежным решением для коммутации?

4b9b3361

Ответ 1

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

1) Я бы определил язык как маршрут верхнего уровня.

App.Router.map(function() {
    this.resource('language', {path:'/language/:lang_code'}, function() {
        // All other routes
    });
});

Тогда изменение языка будет ссылкой на языковой маршрут с соответствующим кодом языка. Для этого я также определял бы модель языка с атрибутами code, name, flag и т.д. Это также было бы полезно при отображении списка кнопок выбора языка или выпадающих меню.

Также при загрузке подпрограммы вы уже знаете, что такое langugage, и вы можете выбрать модели на текущем языке (например, подумайте о записи в блоге, которая отличается на каждом языке). Используйте this.modelFor('language'), чтобы получить текущий язык в любом подпрограмме.

2) Это сложно. AFAIK нет открытого API для получения текущего URL со всеми динамическими сегментами. В контроллере приложений есть свойство currentPath, но оно не включает динамические переменные маршрута. Есть также некоторые внутренние переменные Ember, но я не буду использовать их, поскольку они могут измениться. Вы также можете исследовать текущий URL-адрес маршрутизатора: this.get('router.url'). Также вы можете обойти ember и использовать window.location.href для прямого чтения URL. Но я бы не потратил слишком много времени на это. Пользователи редко меняют свой язык (обычно при первом посещении), и это не большая проблема для перенаправления на индексный маршрут при изменении языка. Я бы сохранил его в cookie или локальном хранилище, а затем не нужно менять язык позже. Если Ember придумает хороший и простой способ сделать это, вы можете легко добавить эту функцию позже.

3) Я бы ничего не помещал в шаблон приложения, поскольку он не переводится. Используйте шаблон языка вместо шаблона приложения, а затем все нужно повторно отобразить при переключении языка.

4) Я думаю, что тексты не обновляются автоматически, поскольку в настоящее время они не привязаны друг к другу. Но это прекрасно, потому что не очень хорошая идея иметь двухсторонние привязки для всех текстов, так как это может замедлить работу системы. Поэтому просто поставьте язык как маршрут верхнего уровня, и все должно работать нормально:)

Ответ 2

Вы можете использовать метод просмотра rerender(), таким образом вам не придется переключаться на фиктивный URL:

updateLanguage: function(lang) {

    //Send xhr to get a dictionary for corresponding language
    this.getDictionary(lang).then(successCb, failureCb);

    //If dictionary was retrieved, set translations property and 
    function successCb(response) {
        Ember.I18n.translations = response;
        $.each(Ember.View.views, function(index, view) {
          view.rerender();
        });
    };

    function failureCb(response) {
        console.error('Dictionary for this language is not available');
    };
}

Ответ 3

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

CAVEAT: Это работает только в том случае, если вы используете Ember с помощью Rails (но, возможно, его можно адаптировать для работы с любой серверной инфраструктурой).

В Rails i18n-js gem интегрируется с локалями Rails по умолчанию. Динамическое переключение в Ember - огромная боль, потому что вы должны вручную перерисовать все виды или reset приложение, чтобы обновить язык при изменении I18n.locale.

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

Конфигурация RAILS:

Сделайте свое действие контроллера индекса ember # следующим образом:

def index
  if params[:locale]
    I18n.locale = params[:locale]
  end
end

Затем в вашем html-шаблоне добавьте эту единственную строку javascript:

<html>
  <head>
    <%= stylesheet_link_tag :application, :media => :all %>
    <%= stylesheet_link_tag    "application", 'http://fonts.googleapis.com/css?family=Roboto:400,300,300italic,100,700' %>
    <%= stylesheet_link_tag    "application", 'http://fonts.googleapis.com/css?family=Roboto+Condensed:400,300,300italic' %>
    <%= javascript_include_tag :application %>
    <title>Review Blaster 9000</title>

<!-- SET LOCALE USING RAILS PARAMETER PARSING -->
    <script>I18n.locale = '<%=I18n.locale%>';</script>
<!-- END SET LOCALE -->

  </head>
  <body>

<!-- Start Ember.js -->
      <%= yield %>
<!-- End Ember.js -->

  </body>
</html>

Затем в вашем шаблоне укажите языковые переключатели следующим образом:

<a href='/?locale=en'>English</a>
<a href='/?locale=es'>Spanish</a>
...etc...

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