2017-11-08 9 views
1

TypeScriptに書かれているcalendarウィジェットがあります。リスナを別の関数にバインドすることはできますが、コンストラクタに渡されたオブジェクトconfigの関数を他の誰かがオーバーライドするまで、この別個の関数をデフォルトの機能にします。コンストラクタでは、私はオブジェクトに定義されている場合のオーバーライド機能その他のデフォルト機能

{ 
    container: 'xxx', 
    cellClick: function(sender, event, data) { 
    // custom functionality 
    } 
} 

がどのように私は私の基底クラスで機能cellClickを定義したときに、私は、この関数にイベントリスナーをバインドしているであろうセルのためのいくつかのデータを渡すために、私のtd細胞をレンダリングすることができます似た何かを渡していますセルの既定の機能をいくつか持ちますが、オブジェクト内の関数を定義してクリックしたセルのデータで上書きする場合は、

私はそれに似ていますが、これはリスナーを直接config関数にバインドします。私はその本当に簡単に私のsetterでそれを行うことを賭けるが、私はそれがどのように数字がわからない。

td.addEventListener('click', function() { 
    this.config.cellClick(td, event, data); 
}) 

EDIT: これは単にthead, tbody and tfoot

defaultConfig = { 
       container: '', 
       dataSource: [], 
       currentDate: new Date(), 
       currentView: 'month', 
       views: [ 
        { type: 'Day' }, 
        { type: 'Week' }, 
        { type: 'Month' } 
       ], 
       startDayHour: 8, 
       endDayHour: 20, 
       cellDuration: 60, 
       todayHighlight: true, 
       cellClick: this.cellClick, 
       eventClick: this.eventClick, 
       showAllDayPanel: false, 
       disabledDays: [], 
       resources: { 
        dataSource: [], 
        field: null 
       }, 
       groupBy: null, 
      } 

      set config(cfg: my.core.calendar.iCalendarConfiguration) { 
       if (cfg) { 

        for (var key in cfg) { 
         if (cfg[key] == null) { 
          cfg[key] = this.defaultConfig[key]; 
         } 
        } 

        if (cfg.cellClick != null) { 
         cfg.cellClick.bind(this.cellClick); 
        } 

        this.configuration = cfg; 
        this.MonthLength = new Date(cfg.currentDate).getMonth(); 
        this.weekDayStart = cfg.currentDate; 
        this.weekDayEnd = cfg.currentDate; 
       } 
      } 

      get config(): iCalendarConfiguration { 
       return this.configuration; 
      } 

      ............. 

      constructor(config: iCalendarConfiguration) { 
       super(); 

       this.element.className = "table table-bordered table-responsive col-sm-12"; // could be readed from config but tbd 
       this.config = config; 
       this.appointmentsArray = config.dataSource; 
       this.tools = new my.calendar.CalendarTools(); 

       /** 
       * Append the element to the container 
       * which is defined in the config. 
       */ 
       document.getElementById(config.container).appendChild(this.tools.createDiv('', 'row', this.parentID)).appendChild(this.element); 
      } 

      abstract createCalendar(); 

      abstract bindAppointments(view: string); 

      abstract Next(sender, e, data) 

      abstract Previous(sender, e, data) 

      abstract TabClick(sender: any, event: any, data: any) 

      abstract initialize() 

      abstract onResize() 

      abstract cellClick(sender: any, event: any, data: any) 

      abstract eventClick(sender: any, event: any, data: any) 

のためのオブジェクトを作成し、抽象クラスとそのクラスを拡張するクラスcalendarがあるTableクラスを拡張して、私のabstractクラスであります構成オブジェクトでインスタンス化されます。

export class Calendar extends my.core.calendar.CalendarTable { 
     weeklyView: my.calendar.WeeklyView; 
     monthlyView: my.calendar.MontlyView; 
     dayView: my.calendar.DayView; 

     constructor(cfg: my.core.calendar.iCalendarConfiguration) { 
      super(cfg); 

      this.weeklyView = new my.calendar.WeeklyView(this); 
      this.monthlyView = new my.calendar.MontlyView(this); 
      this.dayView = new my.calendar.DayView(this); 
     } 


     onResize() { 
      /** 
      * Repaint all appointments on window resize 
      * For many reasons 
      */ 
      this.bindAppointments(); 
     } 

     createCalendar() { 

      /** Clear everything on change */ 
      if (this.tBody.rows.length > 0) { 
       this.tBody.clear(); 
       this.tHead.clear(); 
      } 

      switch (this.config.currentView) { 
       case "month": 
        this.monthlyView.createMontlyView(); 
        break; 
       case "day": 
        this.dayView.createDayView(); 
        break; 
       case "week": 
        this.weeklyView.createWeeklyView(); 
        break; 
      } 

      this.bindAppointments(); 
     } 

     bindAppointments() { 
      /** Remove the events div for week/day view. Its here because reasons. */ 
      if (this.element.parentElement.querySelector("#events") !== null) { 
       let child = document.getElementById('events'); 

       this.element.parentElement.removeChild(child); 
      } 

      switch (this.config.currentView) { 
       case "month": 
        this.monthlyView.bindMonthAppointments(); 
        break; 
       case "day": 
        this.dayView.bindDayAppointments(); 
        break; 
       case "week": 
        this.weeklyView.bindWeekAppointments(); 
        break; 
      } 
     } 

     Next(sender, e, data) { 
      switch (this.config.currentView) { 
       case "month": 
        this.monthlyView.monthNavigationChange(true); 
        break; 
       case "day": 
        this.dayView.dayNavigationChange(true); 
        break; 
       case "week": 
        this.weeklyView.weekNavigationChange(true); 
        break; 
      } 
      this.createCalendar(); 
      this.updateLabels(); 
     } 

     Previous(sender, e, data) { 
      switch (this.config.currentView) { 
       case "month": 
        this.monthlyView.monthNavigationChange(false); 
        break; 
       case "day": 
        this.dayView.dayNavigationChange(false); 
        break; 
       case "week": 
        this.weeklyView.weekNavigationChange(false); 
        break; 
      } 
      this.createCalendar(); 
      this.updateLabels(); 
     } 

     TabClick(sender: any, event: any, data: any) { 

      switch (sender.id.toLowerCase()) { 
       case "day": 
        this.tools.setActiveTab(this, 'day', event); 
        // update currentdate 
        break; 
       case "month": 
        this.tools.setActiveTab(this, 'month', event); 
        // update currentdate 
        break; 
       case "week": 
        this.tools.setActiveTab(this, 'week', event); 
        // update currentdate 
        break; 
      } 
      this.createCalendar(); 
      this.updateLabels(); 
     } 


     updateLabels() { 
      let date = new Date(this.config.currentDate); 
      switch (this.config.currentView) { 
       case "month": 
        this.currentDateMonth.value = String(this.calendar_months_label[date.getMonth()]) + ' ' + String(date.getFullYear()); 
        break; 
       case "day": 
        this.currentDateMonth.value = String(this.config.currentDate.getDate()) + ' ' + String(this.calendar_months_label[this.config.currentDate.getMonth()]) + ' ' + String(this.config.currentDate.getFullYear()); 
        break; 
       case "week": 
        this.currentDateMonth.value = String(this.tools.getPreviousWeekStr(this.weekStart, this.weekEnd, this.calendar_months_label[this.config.currentDate.getMonth()], this.config.currentDate.getFullYear())); 
        break; 
      } 
     } 

     initialize() { 
      this.tools.createNavigation(this, this.config); 
      this.createCalendar(); 
      this.bindAppointments(); 
     } 

     cellClick(sender, event, data) { 
      console.log('fired up from mycalendar'); 
     } 

     eventClick(sender, event, data) { 

     } 

    }; // end class basic 

viewレンダリング、ロジックなどの3つのクラスがあり、テーブルオブジェクトを取得して何らかの処理を行います。

これを初期化する方法は次のとおりです。

var calendar = new my.calendar.Calendar({ 
     container: 'calendarTestContainer', 
     dataSource: data, 
     views: [ 
      { type: 'Week' }, 
      { type: 'Day' }, 
      { type: 'Month' } 
     ], 
     currentDate: new Date('2017-03-15'), 
     currentView: 'week', 
     startDayHour: 8, 
     disabledDays: [6], 
     cellDuration: 30, 
     resources: { 
      dataSource: staffs, 
      field: 'UID' 
     }, 
     endDayHour: 24, 
     cellClick: function (sender, e, data) { 
      // this has to be overrided 
     }, 
     showAllDayPanel: true 
    }).initialize(); 

私はOOPには本当にないんだので、私は再因子提案を開いています。

+0

クラスを共有してください – InferOn

+0

クラスを追加してください。 – Denisx

答えて

1

あなたはデフォルトの機能で、デフォルトのオブジェクトを提供することができる:あなたのconfigオブジェクトを持っている場合

defaults = { 
    option1: 'value1', 
    cellClick: function() {/*do your default stuff here*/} 
} 

は、あなたがObject.assignを使用してそれらをマージすることができます

Object.assign(defaults, config || {}); 

あなたdefaultsオブジェクトは、現在すべて含まれていconfigオブジェクトに値がない限り、デフォルト値。今すぐ使用できます

td.addEventListener('click', defaults.cellClick) 

これは、デフォルト機能または上書き機能をハンドラーとして追加します。

+0

いい感じですが、私はセルのクリックがクラスメソッドであり、オブジェクト内の関数ではないことを望みます。私は、デフォルトのcellClickクラスメソッドを呼び出す場合、それは動作するのですか? – Denisx

+0

'' defaults''はクラスのプロパティでなければならないので、 '' defaults = {cellClick:theNameOfYourMethod} ''を使うことができます。それでもまだ適切でない場合は、クラスの関連部分を共有する必要があります(InferOnは既にコメントされています)。 –

+0

私はそれをしました。クラス – Denisx

関連する問題