这个问题的简短版本:我正在尝试在特定事件发生时(语言更改)重新呈现我的ApplicationView。 ApplicationView仅包含一个简单的插座,但在重新渲染时,此插座仍为空。那么,重新渲染整个页面的正确方法是什么?
简化的应用程序代码(http://jsfiddle.net/6ZQh7/2/):
Ember.Handlebars.registerHelper('t', function() {
return App.get('language') == 'en' ? 'Hi there!' : 'Hallo!';
});
App = Ember.Application.create({
language: 'en',
ApplicationView: Em.View.extend({
templateName: 'application'
}),
TestView: Em.View.extend({
templateName: 'test'
}),
ApplicationController: Em.Controller.extend(),
Router: Em.Router.extend({
root: Em.Route.extend({
toggleLanguage: function(router) {
App.set('language', App.get('language') == 'en' ? 'nl' : 'en');
// view.parentView resolves to the ApplicationView
router.get('applicationController.view.parentView').rerender();
},
index: Em.Route.extend({
route: '/',
connectOutlets: function(router) {
router.get('applicationController').connectOutlet('test')
}
})
})
})
});
对应的HTML:
<script type="text/x-handlebars" data-template-name="application">
<h1>{{t whatever}}</h1>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="test">
<h2>My Test Page</h2>
<a href="#" {{action toggleLanguage}}>Toggle language.</a>
</script>
进行一些调试(好吧,有些;几个小时),似乎在重新渲染时,呈现出口的ContainerView没有上下文,这意味着没有currentView(这个上下文绑定了,这意味着根本没有任何内容呈现出来。从头开始,有一个工作环境;如果我使用调试器在ContainerView #init中调用this.get('templateData.keywords.view.context')
,我会得到applicationcontroller。有趣的是,this.get('templateData.keywords.view.context.view')
(它应该返回插座的视图)返回undefined,而`this.get('templateData.keywords.view.context')。get('view') do < / em>返回视图。
上下文:我正在尝试编写一个国际化的Ember.js应用程序,其中包含一个简单的翻译助手,以当前设置的语言输出字符串(与Ember-I18n一起使用)。目前更改语言需要重新加载页面,因为这些语言字符串是未绑定的(我会理所当然地说,因为语言更改很少,并且创建绑定到页面上的每个字符串听起来都是个坏主意)。但是,我想重新渲染而不是重新加载。
答案 0 :(得分:0)
我有点基本的方法, 创建语言对象,如...
App.Languages = {};
App.availableLanguages = Em.A([App.Languages.En, App.Languages.Pirate]);
App.Languages.En = Em.Object.extend({
languageName: "English",
appName: "My application Name"
})
App.Languages.Pirate = Em.Object.extend({
languageName: "Pirate",
appName: "!!!Zzzz"
})
App.set('language', App.Languages.En);
把手助手
Em.Handlebars.registerHelper('loc', function(key){
currentLanguage = Ember.get('language');
value = currentLanguage.get('key');
return Ember.String.htmlSafe(value);
})
用法:
{{loc appName}}
改变语言: 在页面顶部的下拉列表,如
{{Ember.Select contentBinding=App.availableLanguages optionValuePath="content" optionLabelPath="content.languageName" selectionBinding="App.language"}}
因此,当语言发生变化时,由于ember绑定,值会更新:)
答案 1 :(得分:0)
我通过向应用程序视图添加一个观察者方法解决了完全相同的问题,该方法监听语言设置中的更改,如果它检测到更改,则使用rerender()方法重新呈现视图。
我有语言控制器:
FLOW.languageControl = Ember.Object.create({
dashboardLanguage:null,
content:[
Ember.Object.create({label: "English", value: "en"}),
Ember.Object.create({label: "Dutch", value: "nl"}),
Ember.Object.create({label: "Spanish", value: "sp"}),
Ember.Object.create({label: "French", value: "fr"})],
changeLanguage:function(){
locale=this.get("dashboardLanguage.value");
console.log('changing language to ',locale);
if (locale == "nl") {Ember.STRINGS=Ember.STRINGS_NL;}
else if (locale == "fr") {Ember.STRINGS=Ember.STRINGS_FR;}
else if (locale == "sp") {Ember.STRINGS=Ember.STRINGS_SP;}
else {Ember.STRINGS=Ember.STRINGS_EN;}
}.observes('dashboardLanguage')
});
在手柄文件中有一个下拉列表:
<label>Dashboard language: {{view Ember.Select
contentBinding="FLOW.languageControl.content"
optionLabelPath="content.label"
optionValuePath="content.value"
selectionBinding="FLOW.languageControl.dashboardLanguage" }}
</label>
一个(简化的)导航视图,它呈现顶部导航:
FLOW.NavigationView = Em.View.extend({
templateName: 'navigation',
selectedBinding: 'controller.selected',
onLanguageChange:function(){
this.rerender();
}.observes('FLOW.languageControl.dashboardLanguage'),
});
当navigationView检测到语言更改(由用户从保管箱中选择语言引起)时,导航视图将被重新呈现。
你可以在Application视图上做同样的事情,只是我只需要重新渲染导航视图。