1

如何将 ArrayController.content 绑定到视图,以便根据 ArrayController 中的对象绘制画布。

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存在each的功能ArrayController

首先,我会将您的阵列控制器从 更改andonControllerandonsController. 复数有助于清楚地表明它正在管理 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(<-注意拼写更改)之类的属性绑定到给定用途的已知有效路径,并访问该内部变量的属性。(我也不会绑定上下文属性,我认为这是一种反模式)。

通常,如果您依赖于在外部设置的属性,并且在某些情况下可能未设置,或者不一定指向您期望的对象,我会避免直接在您的课程中使用它和而是定义一个绑定。(我特别指的是内置属性,例如controllercontext行为可能会有所不同。您自己的属性可以定义合理的默认值并记录已知行为,当然可以安全地直接在视图中使用)。您不仅可以避免依赖在所有情况下可能都不相同的行为(或者更糟糕的是,被认为是私有或内部并且将来可能会改变的行为),然后您可以用计算属性替换您的内部属性,或者只是将其绑定到您想要的任何位置,并且无需更新您的参考资料

于 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 回答