【问题标题】:Emberjs-1.0 component and compute property in controllerEmberjs-1.0 组件和控制器中的计算属性
【发布时间】:2013-10-21 01:20:18
【问题描述】:

我将控制器传递给 emberjs component。控制器有一个名为 dateArray 的计算属性,其中包含一个日期数组。单击指向约会模板的 #linkTo 后,我可以进入控制台并执行以下操作:

    b = App.__container__.lookup("controller:appointment")
    c = b.get('dateArray')
    and it returns [Array[2]]

但是,当我使用

将该控制器传递到 emberjs 组件
      {{date-picker datePickerController=controller}}

在组件内部,我可以使用下面的代码获取控制器的正确实例

 datePicker = _this.get('datePickerController');
 console.log(datePicker), shows the dateArray with its content.

但数组显示为空,当我使用下面的代码根据上面的实例创建它时。

  controllerContent = datePicker.get('dateArray'); 

但是,如果我在约会模板的把手表达式中添加 dateArray,它会呈现其内容:

  {{dateArray}}

当控制器实例 emberjs 组件 具有 dateArray

控制器:

App.AppointmentController = Ember.ObjectController.extend({
   needs: [ 'timeSlot'],
   timeSlotController: Ember.computed.alias('controllers.timeSlot'),
   dateArray: function(){
     _this = this;  

     fetchDates = [ ];

    var aa = _this.get('content'); 

    var yy = aa.get('timeSlots')

    yy.then(function(hh){
        nn = hh.map(function(item){ return moment.utc(item.get('startTime')).format("YYYY-MM-DD"); });

     pp =  fetchDates.pushObjects([nn]);

     return nn;
    });  

    return fetchDates;
  }.property('content.@each.timeSlots')


});

emberjs 组件:

App.DatePickerComponent = Ember.Component.extend({
   datePickerController: null,

   didInsertElement: function() {
     this._super();
     _this = this;
     var datePicker;

     datePicker = _this.get('datePickerController');
    //console.log(datePicker);

     var controllerContent = datePicker.get('dateArray');    

    //returns nil
     alert(controllerContent); 

    });// closes didInsertElement

  }

 });

【问题讨论】:

  • 如果你在 dateArray 计算属性中添加一个断点,当你在这一行再次调用 get 时它是否会被命中: var controllerContent = datePicker.get('dateArray');

标签: javascript ember.js ember-router


【解决方案1】:

您的问题是您的dateArray 属性是异步的,因为您使用的是yy.then

会发生这样的事情:

您调用datePicker.get('dateArray') 这个触发器yy.then 但它不会立即解决,您将fetchDates 作为空数组返回。当yy.then 加载时,它将使用fetchDates.pushObjects([nn]) 填充数组,因此更新模板。

我建议您观察数组的变化以执行您想要的操作:

App.DatePickerComponent = Ember.Component.extend({
  datePickerController: null,
  dateArrayChanged: function() {
    var dateArray = this.get('datePickerController.dateArray');
    // now date array have elements
  }.observes('datePickerController.dateArray.[]')
 });

【讨论】:

  • 感谢@Márcio 的有用解释。你是对的,因为我现在可以从 dateArrayChanged 中获取数组。对于从 dateArrayChanged 内部更新以包含日期的 dat 函数 返回 undefined 的原因,您有什么建议吗?它们都在 jsfiddleDatePickerComponent 中定义
  • 在 dat 函数中使用 b = this.get('datePickerController.dateArray');不要忘记使用 get 和 set 来读取/更新 ember 对象的属性
  • @Edu,感谢您的建议。我还有一个问题,用 alert(this.dat()); 之类的东西调用 didInsertElement 中的 dat 函数,仍然返回 undefined , 事件虽然在 dat 函数或方法 内,但我有 alert(this.get('datePickerController.dateArray')) 它返回正确的东西。这是一个 updated jsfiddle。在 datePicker 组件中,dat 函数 定义在 didInsertElement 之后。谢谢。
【解决方案2】:

在 Ember 中,控制器是一种奇怪的传递方式,它只是模型上的装饰器,如果您的模型在控制器下发生更改,您的控制器可能会完全不同(也许这是您的意图)。您可以尝试将 dateArray 传递给组件。

【讨论】:

  • 这通过在组件的模板上显示来工作,但是,我正在使用这个 a.forEach(function(item) { return item;}); 来尝试循环它在组件本身中,它仍然是未定义的。任何建议