4

この質問の短いバージョン: 特定のイベント (言語の変更) が発生したときに 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 がありません (このコンテキストにバインドされています)。 、つまり、アウトレットには何もレンダリングされません。スクラッチ、作業コンテキストがあります。this.get('templateData.keywords.view.context')デバッガーを使用して ContainerView#init を呼び出すと、アプリケーション コントローラーが取得されます。興味深いことに、this.get('templateData.keywords.view.context.view')(アウトレットのビューを返す必要があります) は undefined を返しますが、`this.get('templateData.keywords.view.context').get('view')ビューを返します。

コンテキスト: 国際化された Ember.js アプリを作成しようとしています。これには、現在設定されている言語 (Ember-I18n と組み合わせて使用​​) で文字列を出力する単純な翻訳ヘルパーが含まれています。現在、言語を変更するには、これらの言語文字列がバインドされていないため、ページのリロードが必要です (言語の変更はまれであり、ページ上のすべての文字列にバインドを作成するのは悪い考えのように聞こえるため、当然のことながらそう言えます)。ただし、リロードする代わりに再レンダリングしたいだけです。

4

2 に答える 2

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

handlebars ファイルのドロップダウンで:

<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 が言語の変更 (ユーザーがドロップボックスから言語を選択したことが原因) を検出すると、navigationView が再レンダリングされます。

アプリケーション ビューでも同じことができます。ナビゲーション ビューを再レンダリングする必要があるだけです。

于 2012-10-24T20:03:33.620 に答える
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 バインディングのおかげで値が更新されます:)

于 2012-10-22T12:27:06.020 に答える