React-Rails: используйте компоненты с переводами I18n

Я добавил в свой проект react-rails gem и хочу использовать его для переведенных компонентов.

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

Рабочий сценарий

# app/view/example/_react_component.coffee.erb
DOM = React.DOM

FormInput = React.createClass
  displayName: "FormInput"
  render: ->
    DOM.div
      className: 'row control-group'
      DOM.div
        className: 'form-group col-xs-12 floating-label-form-group controls'
        DOM.label
          htmlFor: @props.id
          @props.label
        DOM.input
          id: @props.id
          className: 'form-control'
          placeholder: @props.placeholder
          type: @props.type
        DOM.p
          className: 'help-block text-danger'

formInput = React.createFactory(FormInput)

window.ValidationFormInput = React.createClass
  displayName: "ValidationFormInput"

  getInitialState: ->
    { }

  render: ->
    formInput
      id: "<%= t('validation_form.id') %>"
      label: "<%= t('validation_form.label') %>"
      placeholder: "<%= t('validation_form.placeholder') %>"
      type: 'text'

validationFormInput = React.createFactory(ValidationFormInput)

# app/view/example/index.html.erb
<%= react_component('ValidationFormInput', {}, {class: "container"}) %>

Желаемый сценарий (не работает)

# app/assets/javascripts/components/form_input.coffee
DOM = React.DOM

FormInput = React.createClass
  displayName: "FormInput"
  render: ->
    DOM.div
      className: 'row control-group'
      DOM.div
        className: 'form-group col-xs-12 floating-label-form-group controls'
        DOM.label
          htmlFor: @props.id
          @props.label
        DOM.input
          id: @props.id
          className: 'form-control'
          placeholder: @props.placeholder
          type: @props.type
        DOM.p
          className: 'help-block text-danger'

formInput = React.createFactory(FormInput)

# app/view/example/_react_component.coffee.erb
window.ValidationFormInput = React.createClass
  displayName: "ValidationFormInput"

  getInitialState: ->
    { }

  render: ->
    formInput
      id: "<%= t('validation_form.id') %>"
      label: "<%= t('validation_form.label') %>"
      placeholder: "<%= t('validation_form.placeholder') %>"
      type: 'text'

validationFormInput = React.createFactory(ValidationFormInput)

# app/view/example/index.html.erb
<%= react_component('ValidationFormInput', {}, {class: "container"}) %>

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

заранее спасибо

Изменить

Чтобы сделать переводы доступными, я нашел gem I18n-js. После установки я могу легко запустить задачу rake, чтобы создать js-версию моих config/locales/* переводов.


person mabe02    schedule 09.06.2016    source источник
comment
Примечание: избегайте js.erb и coffee.erb любой ценой =) Проверьте мой ответ ниже.   -  person Abdo    schedule 09.06.2016


Ответы (1)


Отличный вопрос.

Есть несколько способов сделать это.

1- Обычно это вопрос не только о том, как передавать данные из Rails в React, но и о том, как вообще передавать данные в Javascript. Вы можете хранить данные в meta в заголовке и получать к ним доступ из Javascript. Таким образом, вы все еще можете сжимать JS и быстро. (Вместо js.erb и т. д.)

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

3- Создайте свой собственный переводчик Javascript. Вот пример CoffeeScript, который я создал; не забудьте добавить его в список ваших активов перед другими файлами. В моем коде я беру локаль из meta (как вы можете видеть в коде). Не стесняйтесь редактировать это.

class Translator
  @en = {
    internet_connection_lost: "Your internet connection has been lost"
    attempting_to_reconnect: "Attempting to reconnect!"
    failed_to_reconnect: "Failed to reconnect..."
    connection_success: "Connected"
    reconnecting: "Reconnecting..."
    bid_received: "Bid received. New balance $$bid_balance$$"
  }

  @ar = {
    internet_connection_lost: "لقد فقدت الاتصال بالإنترنت"
    attempting_to_reconnect: "نحاول إعادة الاتصال!"
    failed_to_reconnect: "لم تنجح إعادة الاتصال بالشبكة..."
    connection_success: "متصل بشبكة الإنترنت"
    reconnecting: "إعادة الاتصال جارية..."
    bid_received: "تم تلقي العرض. رصيد جديد $$bid_balance$$"
  }

  @get_translations: (locale) ->
    switch (locale)
      when 'en'
        @en
      when 'ar'
        @ar

  @translate: (val, interpolation) ->
    # get locale from meta
    locale = $("meta[name='locale']").attr("content") || "en"
    translation = Translator.get_translations(locale)[val]

    if interpolation
      console.log "#{JSON.stringify(interpolation)}"

    for k,v of interpolation
      console.log "#{translation} : #{k} : #{v}"
      translation = translation.replace(k, v)

    return translation

window.Translator = Translator

И вот как вы можете использовать переводчик

  message = Translator.translate(
    "bid_received", { "$$bid_balance$$": 10 }
  )
person Abdo    schedule 09.06.2016
comment
Пожалуйста; Надеюсь, это то, что вы ищете :-) - person Abdo; 09.06.2016
comment
На самом деле мне было интересно, есть ли простой способ написать класс Translator, который автоматически принимает все переводы в config/locales/*? - person mabe02; 09.06.2016
comment
Мета-решение может сделать это. Ваши переводы — это просто файлы YAML; все, что вам нужно сделать, это иметь маршрут, который может быть преобразован в JSON и внедрить его как скрипт. Моя проблема с этим решением заключается в том, что оно будет делать это каждый раз, а текст не сжимается. Кроме того, вам придется исправить мой интерполятор, чтобы принять %something =) - person Abdo; 09.06.2016
comment
Что касается переводов, я действительно нашел этот гем I18n.js, который делает то, что я ожидал! Еще раз спасибо за вашу помощь - person mabe02; 09.06.2016