如何在Rails的Coffee.erb文件中用JS/Coffee变量动态设置I18n locale?
解决Rails Coffee.erb中动态设置Locale的问题
首先得明确一个核心点:你没法直接在Rails的erb表达式(服务器端代码)里引用JS/Coffee的客户端变量。原因很简单:Rails的erb模板是在服务器上先渲染成Coffee/JS代码,然后才发送到浏览器执行客户端逻辑。服务器渲染的时候,客户端的变量还根本不存在,两者完全不在一个运行环境、时间点上。所以你原来想直接把JS变量塞进I18n.t的locale参数里的语法,是行不通的。
那该怎么实现动态设置locale的需求呢?这里给你两个常用的方案:
方案一:预加载翻译到客户端,用前端逻辑处理
如果你的翻译量不大,或者需要频繁切换语言不希望每次都发请求,可以把需要的翻译数据提前注入到前端全局变量里,然后用前端代码动态获取:
- 先在Rails的布局文件(比如
app/views/layouts/application.html.erb)里,把翻译数据转成JSON输出到全局变量:
<script> // 把服务器端的翻译数据注入到前端 window.appTranslations = <%= I18n.backend.send(:translations).to_json %>; </script>
- 然后在你的
mysite.coffee.erb里,直接用前端变量获取对应locale的翻译:
# 这里的currentLocale是你的前端变量,比如从用户的语言选择器里获取 currentLocale = 'sv' # 可以换成动态获取的变量,比如$('#language-select').val() # 从全局翻译数据里拿到对应的值 carUrl = window.appTranslations[currentLocale]?.url?.car # 然后把这个值赋值到你需要的地方,比如某个配置对象里 yourConfig = 'car': carUrl
方案二:通过AJAX请求动态获取翻译
如果你的翻译量很大,或者不想把所有翻译都暴露在前端,可以通过AJAX请求服务器,传递当前的locale参数来获取对应的翻译值:
- 先在Rails里写一个处理翻译请求的API控制器:
# app/controllers/api/translations_controller.rb class Api::TranslationsController < ApplicationController skip_before_action :verify_authenticity_token # 如果需要的话,根据你的CSRF配置调整 def show translation_key = params[:key] target_locale = params[:locale] || I18n.default_locale translation_value = I18n.t(translation_key, locale: target_locale) render json: { value: translation_value } end end
- 配置对应的路由:
# config/routes.rb Rails.application.routes.draw do namespace :api do get 'translations/:key', to: 'translations#show' end # 其他路由... end
- 最后在
mysite.coffee里(其实这里不需要erb后缀了,因为不需要服务器端渲染),用AJAX请求获取动态翻译:
# 定义一个获取翻译的函数 fetchTranslation = (key, locale, callback) -> $.get "/api/translations/#{key}", { locale: locale }, (response) -> callback(response.value) # 使用示例 currentLocale = 'sv' # 你的前端动态变量 fetchTranslation 'url.car', currentLocale, (carUrl) -> # 拿到翻译后的URL,做后续处理 yourConfig = 'car': carUrl
再总结一下你问的两个关键点:
- 能不能在Coffee文件的Rails表达式里获取JS/Coffee变量? 完全不行,因为服务器端渲染和客户端代码执行是完全分离的两个阶段,服务器根本访问不到客户端的变量。
- 原来的动态设置语法可行吗? 不可行,因为
:sv是服务器端的静态值,你没法直接替换成客户端变量,服务器会把客户端变量当成未定义的服务器端变量报错。
内容的提问来源于stack exchange,提问作者IT_puppet_master
相关产品推荐
相关产品推荐

