2012-10-22 63 views
4

此問題的簡短版本:當特定事件發生(語言更改)時,我試圖重新呈現我的ApplicationView。 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')確實返回視圖。

上下文:我試圖編寫一個國際化的Ember.js應用程序,它包含一個簡單的翻譯助手,以當前設置的語言(與Ember-I18n一起使用)輸出字符串。目前改變語言需要重新加載頁面,因爲這些語言字符串是未綁定的(我會這樣說,因爲語言更改很少,並且創建頁面上每個字符串的綁定聽起來像一個壞主意)。不過,我想重新渲染而不是重新加載。

{{loc appName}} 

更改語言:

+0

我不認爲你需要重申應用程序視圖,如果你只需要應用語言改變...使用綁定直接影響語言w/o重新渲染的應用程序查看 –

+1

是的,但正如我最後段落我不得不爲頁面中的每個字符串創建綁定,即使它們可能永遠不會改變,這似乎是矯枉過正(和潛在的性能瓶頸)。 另外目前我很kindaa只是好奇如何做到這一點:)。 –

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

用法創建語言對象 頁面頂部的下拉菜單,如

{{Ember.Select contentBinding=App.availableLanguages optionValuePath="content" optionLabelPath="content.languageName" selectionBinding="App.language"}} 

因此,當語言被改變時,由於燼綁定的值被更新:)

+0

你所建議的把手助手是沒有約束力的。所以我不認爲這會實際更新,因爲你選擇一種新的語言。 Elte不希望具有約束力,因爲「語言變化很少,並且創建頁面上每個字符串的綁定聽起來像一個壞主意」(這對我來說聽起來很合理)。所以我們回到原來的問題:你如何重新渲染applicationView? –

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> 

和A(簡化的)導航視圖,這使得頂部導航:

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

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

當navigationView檢測到語言改變時(這是由用戶選擇al語言從dropbox),navigationView被重新渲染。

你可以在應用程序視圖上做同樣的事情,它只是我需要重新導航視圖。

+0

是的,這是我做的,只是它不工作,顯然是由於我使用插座的方式(請參閱http://stackoverflow.com/questions/13046521/ember-js-dynamically-switching-layouts-with-網點/)。 –