1

ArrayController 内のオブジェクトに応じてキャンバスを描画するために、ArrayController.content をビューにバインドするにはどうすればよいですか。

jsFiddle - サンプル コード コントローラーの値のバインドは機能していますが、content.values のバインドは機能していません。

質問 1: 概念的な失敗ですか? 問題の詳細情報を見つけることができませんでした。ObjectController では機能しますが、ArrayController では機能しません。

質問 2: Object.values (eq faceColor) が変更された場合、ビューを更新するための最善の解決策は何ですか?

HTML

<script type="text/x-handlebars">

<h1>each</h1>
{{#each App.andonController}}
    {{view "App.AndonView"}}
    {{faceColor}} {{emotionType}}
{{/each}}   

</script>

オブジェクト

App.Andon = Ember.Object.extend({
    emotionType: '',
    faceColor: '',
});

景色

ArrayController の各オブジェクトに対してキャンバス内に要素を描画したいと思います

App.AndonView = Ember.View.extend({

    tagName: "canvas",
    attributeBindings: ['height', 'width'],
    height: 100,
    width: 100,

    controllerBinding:'App.andonController.content',
    faceColorBinding: 'content.faceColor',
    emotionTypeBinding: 'content.emotionType',

    didInsertElement: function(){
        this.drawSmiley();        
    },

    arrayDidChange: function(){
        this.drawSmiley();
    },  

    degreesToRadians : function(degrees) {...},

    drawSmiley: function(){
        ...
        var faceColor = null;
        try {
            faceColor = this.get('faceColor');
            //alert(faceColor);         
        } catch (e) {
            alert('faceColer is empty')
        } 
        ...
    } 
});

コントローラー

App.andonController = Em.ArrayController.create({

    content: [

      App.Andon.create( 
      {
        emotionType: 'happy',
        faceColor: '#00ff00'
      }), 
      App.Andon.create( 
          {
              emotionType: 'sad',
              faceColor: '#665sd'
      } 
   )],

})
4

2 に答える 2

3

これを少し再構築して、オンとオンに直接itemController存在する機能を使用します。eachArrayController

まず、アレイ コントローラを からandonControllerに変更しますandonsController。複数形は、個々のオブジェクトではなく、アンドンのコレクションを管理していることを明確にするのに役立ちます。

次に、個々の andon オブジェクトを管理する 2 つ目のコントローラーを作成します。

App.AndonController = Ember.ObjectController.extend()

今、ループで代わりに行うことができます

{{#each App.andonsController itemController="App.AndonController"}}
    {{view "App.AndonView"}}
    {{faceColor}} {{emotionType}}
{{/each}}   

のインスタンスApp.AndonController(現在はObjectControllerです。つまり、バインディングや計算されたプロパティを含むプロパティのコンテンツ呼び出しに透過的に渡されることを意味します) は、ループ内の各項目に対して作成されます。これは、ビューのコントローラーがそのコンテキストであるためです。 、パスの前に何も追加する必要はなく、サブビューはcontrollerそのコンテキストとして自動的に取得します。

説明するために JSFiddle をフォークしました。

http://jsfiddle.net/H2zPk/

contextあなたのビューでプロパティを使用することについて、私はもっと確信が持てません。これは主にテンプレートで使用するためのものであり、内部で使用すると、たとえばcontextAndonController ではない場所に含めようとすると、後で期待される動作に違反する可能性があります。content代わりに、 (<- スペルの変更に注意してください) のようなプロパティを、指定された用途の既知の有効なパスにバインドし、その内部変数からプロパティにアクセスします。(コンテキストプロパティもバインドしません。それはアンチパターンだと思います)。

一般に、外部で設定されるプロパティに依存している状況があり、特定のケースでは設定されていないか、または期待するオブジェクトを必ずしも指していない可能性がある場合、クラスで直接使用することは避け、代わりにバインディングを定義します。(私は特に、controllerまたはのようなcontext動作が変化する可能性のある組み込みプロパティについて言及しています。独自のプロパティは、妥当なデフォルトを定義し、既知の動作で文書化することができ、もちろんビューで直接使用しても安全です)。すべてのケースで同じではない可能性のある動作 (または、さらに悪いことに、プライベートまたは内部と見なされ、将来変更される可能性のある動作) に依存することを避けるだけでなく、内部プロパティを計算されたプロパティに置き換えるか、単に好きなところに縛って、参照を更新する必要はありません

于 2013-03-18T17:38:00.307 に答える
1

contextBinding を使用することで、この問題をある程度解決できました。テンプレートを次のように変更できます。

{{#each andon in App.andonController}}
    {{view "App.AndonView" contextBinding="andon"}}
    {{faceColor}} {{emotionType}}
{{/each}}

次に、ビューの各値を次のようにフェッチします

this.get('context.faceColor')

等々。私はあなたのフィドルで幸せそうな顔を得ることができました.

http://jsfiddle.net/gcLft/2/

于 2013-03-18T09:38:23.053 に答える