重新渲染ApplicationView与插座 [英] Re-rendering ApplicationView with outlet

查看:88
本文介绍了重新渲染ApplicationView与插座的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题的简短版本:当一个特定的事件发生(语言改变)时,我正在尝试重新渲染我的ApplicationView。 ApplicationView只包含一个简单的插座,但是在重新渲染此插座时仍然为空。那么,重新渲染整个页面的正确方法是什么?

Short version of this question: I'm trying to re-render my ApplicationView when a specific event happens (a language change). The ApplicationView only contains a simple outlet, however on re-rendering this outlet remains empty. So, what is the correct approach to re-render an entire page?

简化的应用程序代码(http://jsfiddle.net/6ZQh7/2/):

Simplified application code (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')(应该返回插座的视图)返回未定义,而this。 get('templateData.keywords.view.context')。get('view') 返回视图。

Doing some debugging (well, some; a few hours of it), it seems that when the re-render occurs, the ContainerView that renders the outlet doesn't have a context, which means no currentView (which is bound to this context), which means nothing is rendered in the outlet at all. Scratch that, there is a working context; if I call this.get('templateData.keywords.view.context') in ContainerView#init using the debugger, I get the applicationcontroller. Interestingly enough though, this.get('templateData.keywords.view.context.view') (which should return the view for the outlet) returns undefined, whereas `this.get('templateData.keywords.view.context').get('view') does return the view.

上下文:试图写一个国际化的Ember.js应用程序,其中包含一个简单的翻译助手,以当前设置的语言输出字符串(与Ember-I18n一起使用)。当前更改语言需要重新载入页面,因为这些语言字符串是未绑定的(我会这么说,因为语言变化很少,并且创建绑定到页面上的每个字符串听起来都是一个坏主意)。但是,我只想重新渲染,而不是重新加载。

Context: I'm trying to write an internationalized Ember.js app, which contains a simple translation helper outputting strings in the currently set language (used in conjunction with Ember-I18n). Currently changing the language requires a reload of the page, as these language strings are unbound (and I would say rightfully so, as language changes are rare and creating bindings to every string on the page sounds like a bad idea). However, I'd like to just re-render instead of reload.

推荐答案

我通过添加观察者解决了完全相同的问题方法到应用程序视图,它监听语言设置中的更改,如果检测到更改,则使用rerender()方法重新呈现视图。

I solved the exact same problem by adding an observer method to the application view, which listens to changes in the language setting, and if it detects a change, rerenders the view using the rerender() method.

我有一个语言控制器:

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')
});

在句柄文件中有一个下拉列表:

with a dropdown in a handlebars file:

<label>Dashboard language: {{view Ember.Select 
  contentBinding="FLOW.languageControl.content" 
  optionLabelPath="content.label" 
  optionValuePath="content.value" 
  selectionBinding="FLOW.languageControl.dashboardLanguage" }}
</label>

还有一个(简化的)导航视图,其中显示了顶部导航:

And a (simplified) Navigation view, which renders the top navigation:

FLOW.NavigationView = Em.View.extend({
  templateName: 'navigation',
  selectedBinding: 'controller.selected',

  onLanguageChange:function(){
    this.rerender();
  }.observes('FLOW.languageControl.dashboardLanguage'),
});

当navigationView检测到语言更改(由用户从保管箱中选择语言造成的) ,导航视图被重新投放。

When the navigationView detects a language change (which was caused by the user selecting a language from the dropbox), the navigationView is rerendered.

您可以在应用程序视图中执行相同的操作,只是我只需要重新导航视图。

You could do the same thing on the Application view, it is just that I only need the navigation view to be rerendered.

这篇关于重新渲染ApplicationView与插座的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆