我正在尝试使用AngularJS开发应用程序,该应用程序应能以多种用户选择的语言工作。我将视图放置在views/en和views/fr等中,因此,如果用户使用英语查看,则所有控制器的模板URL将是views/en/someFile.html,对于法语,它将是/views/fr/someFile.html,依此类推。 。问题是,如何处理由javascript显示的以正确语言显示的随机表单验证消息/警报?例如,在我所有的控制器中,我都有一个$scope.title变量,可在浏览器中设置<title>。如果用户选择其他语言,我也希望更新<title>以使其选择的语言显示。实现此目标的最佳方法是什么? 最佳答案 textService我已经更新了此答案,以反映我当前对这个问题的解决方案。删除模板中的文本数据依存关系是我感觉到的重要问题,因此,我继续为此编写了自己的小模块。如果要使用所有文本插入选项(状态文本和相对文本),则需要使用ui-router来配置路由。这是用法。我将模块放在答案的末尾。 在angular之后但模块定义之前包含text-service.js 声明为依赖项:angular.module("app", ["textService"] 将文本数据对象绑定到它。文本数据对象应模仿您的状态层次结构。例如。:var textData = { home:{//'home'状态 //这里的本地状态文本数据 child {//'home.child'状态 //子状态的文本数据 } }}文本对象应该是对象文字,其语言名称为键:var textData = { 家:{ 标题:{ zh-CN:“首页”, fr:“梅森” } } }}设置语言并将文本对象绑定到textService:app.run(function(textService){ var textData = ... textService .setLanguage(“ en”) .bindText(textData)});将所有文本数据包含在run函数中可能不是理想的-因此,取决于用户是否要使用工厂或许多工厂来注入它:app.factory(“ textData”,function(){ var textData = ... 返回textData}app.run(function(textService,textData){ textService .setLanguage(“ en”) .bindText(textData)}); 有四个基于属性的指令,用于从模板中检索文本。属性名称为: atext-“绝对文本” stext-“状态文本” rtext-“相对文本” text-“文字”要在模板中使用,请添加atext作为属性,并将其值设置为字符串,以查找您感兴趣的文本数据: 所有指令均会将您添加到其中的任何DOM元素的innerHtml替换为文本数据,因此请确保它没有您关心的子DOM元素。指令中的差异主要与查找文本字符串有关。假设我们有以下文本数据对象:var textData = { 标题:{ zh:“索引”, fr:“索引” }, // 老家 家:{ 标题:{en:“ Home”,fr:“ Maison”}, 标头:{en:“标头”,fr:“”} 孩子:{// home.child 标题:{en:“儿童”,fr:“儿童”}, 介绍: { zh:“欢迎儿童”, fr:“ Bienvenueàl'enfant” } } lonelychild:{ //没有文字数据 } }};atext指字符串的绝对位置。因此,atext="title.en"获取“ Index”,而atext="title"会引发错误(目前)。stext指的是相对于当前状态的字符串。例如,如果处于状态“ home”,则stext="title"将获取“ Home”。如果您根本不处于任何状态,它将获取“索引”。如果要导航到“ home.child”状态,它将获取“ Child”。 (注意:这些都是在您将语言设置为“ en”的情况下提供的)rtext指相对文本位置。它的行为与stext相似,不同之处在于它将搜索状态层次结构以查找也要匹配的文本数据。这对于根据状态动态更改标题非常方便: 这会将标题DOM元素的innerHtml替换为最近的“标题”文本数据。因此,如果您处于状态“ home.lonelychild”,则标题仍将绑定到“ Home”(因为它位于父状态的文本数据中)。text该指令的作用与atext相同,只是您不需要指定语言。随语言变化而动态变化的指令是stext,rtext和text。您可以使用例如textService.setLanguage("fr")更改语言。这将$ broadcast一个“ languageChange”事件到所有文本指令,指示它们应该更新。如果要禁止更新,请传递第二个参数,指示是否应执行更新:textService.setLanguage("fr", false) /在状态更改时动态更改的指令是stext和rtext。您可以使用textService.update()强制进行更新我已经尽力使这个插件尽可能快。根据一般经验,每个文本指令都会产生大约1ms的初始处理时间。我认为,其中大部分来自对每个文本数据进行角度初始化的指令。但是,即使在一页上有100个左右的文本指令,动态更新也很快。这是模块和github repo的链接/ * * text-service.js *作者:伊恩·哈格蒂(Ian Haggerty)[email protected] *最后编辑:17/08/2013 * /angular.module(“ textService”,[]) .factory(“ textService”,function($ rootScope,$ log){ / *内部实现* / var textService; textService = { 语言: ””, 状态:“”, textData:{}, / *文本(请求)-文本请求 * @request不含语言的文本的绝对路径-例如“ home.title” * / 文字:函数(请求){ 返回(新功能( “返回参数[0] .textData。” +要求+ (((textService.language)?(“。” + textService.language):“”) ))(textService); }, / * absText(request)-绝对文本请求 * @request附加了语言的文本的绝对路径-例如“ home.title.en” * / absText:函数(请求){ 返回(新功能( “返回参数[0] .textData。” +要求 ))(textService); }, / * relText(request,cut)-作用域文本请求,将搜索状态层次结构 * @request不含语言的文本的相对路径-例如'标题' * @state测试文本数据的状态-默认为当前状态,以递归方式使用 * / relText:函数(请求,状态){ if(state === undefined){ //初始调用函数 状态= textService.state } 尝试{return textService.text((state?state +“。”:“”)+ request)} 抓住{e} { if(!state)return“” //终止以避免无限递归 返回textService.relText(request,state.split(“。”))。slice(0,-1).join(“。”); } }, / * stateText-请求当前状态下的字符串(例如stateText('title') * @request-当前状态下字符串的相对路径 * / stateText:函数(请求){ 返回(textService.state)? textService.text(textService.state +“。” + request):“”; } } //注册状态更改的处理程序 $ rootScope。$ on(“ $ stateChangeSuccess”,函数(事件,toState){ textService.state = toState.name; }); / *公共API * / var textServiceApi = { / * bindText-将整个文本数据绑定到新对象 * @textData-要绑定到的文本数据对象 * / bindText:函数(textData){ textService.textData = textData; $ rootScope。$ broadcast(“ textDataChange”) 返回textServiceApi; }, / * setText()-设置文本数据和更新文本指令的函数 * @request请求字符串,例如'home.title','home.title.en' * @textData文本数据。可以是文字字符串或具有文字数据的对象 * @doUpdate布尔值,指示是否更新文本指令。默认为FALSE。 *示例用法1:setText('home.title.en',“ Title”)-设置不更新的文本字符串 *示例用法2:setText('home.title',{en:“ Title”,fr:“ Maison”},true) *-设置带有更新页面的文本对象 * / setText:function(request,textData,doUpdate){ (新功能( “参数[0] .textData。” +请求+“ =参数[1]” ))(textService,textData) if(!doUpdate)$ rootScope。$ broadcast(“ textDataChange”) 返回textServiceApi }, / * getText()-返回文本数据的函数 * @request对文本的绝对引用 *示例用法:getText('home.title.en'),getText('home.title')//返回文本对象 * / getText:function(request){ 如果(!请求) 返回textService.textData 其他{ 返回(新功能( “返回参数[0] .textData。” +要求 ))(textService) } }, / * setLanguage()-设置当前语言 * @langauge-新语言。例如“ fr”,“ en” * @doUpdate-布尔值,指示是否更新文本指令,默认为TRUE *示例用法:setLanguage(“ fr”)//更改为法语并更新页面 * / setLanguage:函数(语言,doUpdate){ if(doUpdate ===未定义)doUpdate = true; textService.language =语言 $ rootScope。$ broadcast(“ languageChange”) 返回textServiceApi; }, getLanguage:function(){ 返回textService.language; }, / * update()-请求所有文本指令进行自我更新 * / 更新:function(){ $ rootScope。$ broadcast(“ textDataChange”) 返回textServiceApi }, / *由文本指令使用* / 文字:textService.text, absText:textService.absText, relText:textService.relText, stateText:textService.stateText } 返回textServiceApi }) / *文本指令* / .directive(“ text”,function(textService){ 返回{ 限制:“ A”, 链接:函数(作用域,元素,属性){ 函数update(){ element.html(textService.text(attrs.text)) } scope。$ on(“ languageChange”,更新) scope。$ on(“ textDataChange”,更新) update() } } }) / *绝对文本指令* / .directive(“ atext”,函数(textService){ 返回{ 限制:“ A”, 链接:函数(作用域,元素,属性){ 函数update(){ element.html(textService.absText(attrs.atext)) } scope。$ on(“ textDataChange”,更新) update() } } }) / *状态文本指令* / .directive(“ stext”,函数(textService){ 返回{ 限制:“ A”, 链接:函数(作用域,元素,属性){ 函数update(){ element.html(textService.stateText(attrs.stext)) } scope。$ on(“ languageChange”,更新) scope。$ on(“ textDataChange”,更新) scope。$ on(“ $ stateChangeSuccess”,更新) update() } } }) / *相对文本指令* / .directive(“ rtext”,函数(textService,$ log){ 返回{ 限制:“ A”, 链接:函数(作用域,元素,属性){ 功能更新(事件,请求){ element.html(textService.relText(attrs.rtext)) } scope。$ on(“ languageChange”,更新) scope。$ on(“ textDataChange”,更新) scope。$ on(“ $ stateChangeSuccess”,更新) update() } } }) 10-04 16:03