我正在尝试使用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