Ember.ArrayController和Ember.View之间的contentBinding [ember-1.0.0-rc.1.js]

时间:2013-03-18 08:18:30

标签: ember.js handlebars.js

如何将ArrayController.content绑定到View,以便根据ArrayController中的Object绘制画布。

jsFiddle - Sample Code 控制器中值的绑定正在起作用,但不适用于content.values。

问题1: 这是概念上的失败吗?我无法找到问题的详细信息。对于ObjectController它可以工作,但不适用于ArrayController。

问题2: 如果Object.values(e.q。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

中的每个Object中
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'
      } 
   )],

})

2 个答案:

答案 0 :(得分:3)

我会重新调整一下以使用itemController功能,该功能直接存在于eachArrayController上。

首先,我会将您的阵列控制器从andonController更改为andonsController。复数有助于明确它正在管理andons的集合而不是单个对象。

然后我会制作第二个控制器来管理单个andon对象:

App.AndonController = Ember.ObjectController.extend()

现在,在循环中你可以改为

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

App.AndonController的实例(现在是ObjectController,这意味着它将透明地传递给其内容调用,包括绑定和计算属性')将为每个项目创建循环,并且因为视图的控制器是它的上下文,所以你不需要在路径前面添加任何内容,并且subView会自动将controller作为其上下文。

我已经分叉你的JSFiddle来说明:

http://jsfiddle.net/H2zPk/

我更不确定在您的视图中使用context属性。这主要供模板使用,如果您尝试将其包含在context不是AndonController的某个地方,则在内部使用它会导致违反行为期望。我会将content(&lt; - 注意拼写更改)等属性绑定到给定用途的已知有效路径,并访问该内部变量的属性。 (我也没有绑定上下文属性,我认为这是反模式)。

一般情况下,如果您依赖的是外部设置的属性,或者在某些情况下可能未设置,或者可能不一定指向您期望的对象,我会避免直接使用它你的类,而是定义一个绑定。 (我特别指的是内置属性,如controllercontext,其行为可能会有所不同。您自己的属性可以定义合理的默认值并记录已知行为,当然可以直接使用风景)。您不仅要避免依赖于在所有情况下可能不相同的行为(或者更糟糕的是,被认为是私有或内部行为并且将来可能会发生变化的行为),您可以使用计算属性替换您的内部属性或者只是将它绑定到任何你想要的地方,没有炸毁Ember 的风险,无需更新你的参考文件

答案 1 :(得分:1)

通过使用contextBinding,我在这个问题上取得了一些成功。 您可以将模板更改为这样的内容。

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

然后获取视图中的每个值

this.get('context.faceColor')

等等。 我能够让你快乐的脸变成你的小提琴。

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