【问题标题】:Emberjs 1.0, Computed property and template not refreshed when data changesEmber Js 1.0,计算属性和模板在数据更改时不刷新
【发布时间】:2013-10-20 00:53:42
【问题描述】:

我有一个与 datepicker 集成的 emberjs 应用程序。当我单击日期选择器上的日期时,计算属性应该将单击的日期与 *timeslot** 上的日期进行比较,以查看是否存在匹配项,并且我希望模板基于此刷新,或者列出可用的 timeSlots或者说没有。遗憾的是,模板不会刷新或显示新数据。

这是jsfiddle,重要的控制器/路由/模板是timeSlotappointmentdatePicker > 和 datepickerComponenet。

在 jsfiddle 中,您需要单击查看更多并向下滚动,以查看加载的日历和时间段以红色显示的日期。问题是单击任何红色的日期都应该重新渲染 timeSlot 模板并重新计算 displaySelectedDate 计算属性。目前,它仅在您第一次点击日期时呈现 时间段模板,之后该模板不会在所有后续点击中刷新。

这是控制器。似乎计算属性没有被多次调用。结果,之前我在 displaySelectedDate 计算属性上调用了 .volatile 但没有任何变化,所以我将其删除并添加了 observer此处显示,但仍然没有变化。

App.TimeSlotController = Ember.ArrayController.extend({
  needs: 'appointment',
  content: [ ],

 apptId: null,
 apptDate: null,
 day: Ember.A([ ]),

 contentDidChange: function(){
   a = this.get('day'); 
     console.log(a);
   return a;
  }.observes('day'),

  displaySelectedDate: function(){
    a = moment(this.get('apptDate')).unix();

    b = moment.utc(this.get('day').toString()).unix(); 

    x = (a === b);

    return x;

  }.property('day.@each', 'apptDate'),                                                 

});

我通过首先获取约会来填充 timeSlot 的路线

App.TimeSlotRoute = Ember.Route.extend({

   setupController: function(controller, model) {

     self = this;
     self._super(controller, model);

     parent = self.controllerFor('appointment');

     self.controller = controller;

    c =   parent.get('timeSlots').then(function(data){
        f =  self.controller.set('content', data); 

     });          
   }
 })

提供日期数组的日期选择器控制器,这些日期将在日期选择器中着色。如果我们使用未注释版本的 dateArray 计算属性 来获取 appointment startDate,则日期按预期着色。但是,如果注释第一个版本并取消注释第二个版本的 dateArray 计算属性,它获取 timeSlot by startTime,则 calebdar 不会着色。 任何想法为什么会这样

  App.DatePickerController =  Ember.ArrayController.extend({ 
     needs: ['appointments', 'appointment', 'timeSlot'],

   time: Ember.computed.alias('controllers.timeSlot.content'),
   appointments: Ember.computed.alias('controllers.appointments.content'),

   dateArray: function(){
     _this = this;  
     var fetchDates = _this.get('appointments');

     return  fetchDates.map(function(item){ 
       return moment.utc(item.get('startDate')).format("YYYY-MM-DD");
     });
   }.property('appointments.@each.startDate'),

   /*
   dateArray: function(){
     _this = this;  
     var fetchDates = _this.get('time');

     return  fetchDates.map(function(item){ 
      return moment.utc(item.get('startTime')).format("YYYY-MM-DD");
     });

    }.property('timeSlot.@each.startTime'),  
   */
 });

这是相同代码的较小版本,我创建了第二个 jsfiddle。在这个版本中,datePicker 控制器和路由被删除,它的代码被移到 appointment 控制器中。如果单击它,您将看到带有约会的 timeSlots 没有变成应有的红色。

  App.AppointmentController = Ember.ObjectController.extend({

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

});

执行控制台日志建议约会控制器中的dateArray返回一个数组,格式如下:

  [Array[2]]

但是,当使用 dateArray 计算属性 的第一个版本时,datepickerController 返回的数组是由 appointment startDate 为日历着色的形式:

  ["2013-10-18", "2013-10-25", "2013-10-25", "2013-10-18"]

我想要什么

在 datePicker 中单击日期以重新呈现 timeSlot 模板,其次让我能够在日历中加载 timeSlot startTime 或者使用约会控制器或来自 datePicker 控制器dateArray 计算属性的第二个版本。

这是基于第一个 jsfiddle 的日历上约会 startDate 的屏幕截图

这是我尝试根据第二个 jsfiddle 或第一个 jsfiddle 的 datepicker 控制器中注释掉的 dateAarray 属性将 timeSlot startTime 传递给日历时的屏幕截图。请注意,在这两种情况下,日历都没有着色

感谢您的帮助。

【问题讨论】:

  • 你好,看看这个 JSFiddle jsfiddle.net/Xajsr/7
  • 感谢 @Edu 的 jsfiddle。单击日期会显示正确的时间段。 datepicker 组件中仍然存在问题,我已取消注释,beforeShowDay 方法 以显示这一点。我还在上述方法中添加了 *uncommented console.log(events);console.log(checkForDate);。如果 checkForDate 返回 true,则日历是彩色的,否则不是。在 didInsertElement 中,就在 beforeShowDay 上方,我还取消了 console.log(controllerContent); 的注释,并添加了 alert(controllerContent); 返回未定义。 jsfiddle.net/Xajsr/8

标签: javascript ember.js handlebars.js ember-router


【解决方案1】:

存在异步问题,因为 timeSlot 被定义为异步。您可以使用路由中的 afeterModel 挂钩解决此问题。如果这个钩子(也包括 beforeModel 和模型钩子)返回一个 Promise,路由器就会停止,直到 Promise 解决……这是新的预约路由:

App.AppointmentRoute = Ember.Route.extend({
    model: function(params){
      return modelFor('appointments').get(params.appointment_id);  
    },
    afterModel:function(model){
        return model.get('timeSlots');
    }
});

和 JsFiddle http://jsfiddle.net/Xajsr/10/

【讨论】:

  • 感谢@Edu 抽出时间回答这个问题。我很感激。
猜你喜欢
  • 2017-08-14
  • 2016-02-10
  • 2014-07-04
  • 2014-09-22
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
  • 2014-04-06
  • 2018-05-22
相关资源
最近更新 更多