1

I tried use the componente in angular2 as directive. This is code the directive:

export class Datepicker {
    public date : Date;
    public callback : Function;

    constructor() {
        $('.datepicker').datepicker({
            dateFormat: 'dd/mm/yy',
            dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado'],
            dayNamesMin: ['D','S','T','Q','Q','S','S','D'],
            dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb','Dom'],
            monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
            monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'],
            nextText: 'Próximo',
            prevText: 'Anterior',
            showOn: 'button',
            buttonImage: 'http://jqueryui.com/resources/demos/datepicker/images/calendar.gif',
            buttonImageOnly: true,
            onSelect: function(selectedDate) {
                console.log(this.callback);
            }
        });
    }

    setCallback(fn : Function){
        this.callback = fn;
    }
}

In html:

<input class="mdl-textfield__input datepicker" [(ng-model)]="datepicker1" type="text"/>

In my componente use this code:

import {Component, NgIf, FORM_DIRECTIVES, ElementRef} from 'angular2/angular2';
import {Datepicker} from '../datepicker/datepicker';

declare function initMaterial();

@Component({
    selector: 'modal',
    directives: [NgIf, Datepicker, FORM_DIRECTIVES],
    templateUrl: './frontend/components/modal/modal.html',
    styleUrls: ['./frontend/components/modal/modal.css'],
    bindings: [Datepicker]
})

export class Modal {
    public isOpen : boolean = false;
    private dtCompromise : Date;
    private dsCompromise : String;
    private datepicker : Datepicker;

    constructor(datepicker : Datepicker){
        this.datepicker = datepicker;
        this.datepicker.setCallback(function(selectedDate : Date){
            console.log('Date: ' + selectedDate);
        });
    }
}

In html:

<form action="#">
    <div class="mdl-textfield mdl-js-textfield">
        <datepicker callback="selectDate" [(ng-model)]="datepicker"/>
        <label class="mdl-textfield__label" for="dtCompromisse">Data</label>
    </div><br>
    <div class="mdl-textfield mdl-js-textfield">
        <textarea class="mdl-textfield__input" type="text" rows= "5" [(ng-model)]="dsCompromise"></textarea>
        <label class="mdl-textfield__label" for="dsCompromisse">Descrição</label>
    </div>
</form>

When selected date function onSelect is called and console.log print undefined

onSelect: function(selectedDate) {
   console.log(this.callback);
}

Whats is my error?

Emir Marques
  • 2,603
  • 2
  • 16
  • 22
  • Also check it out this response https://stackoverflow.com/questions/35328652/angular2-pass-callback-function-to-child-component-as-input/35329009#35329009 – Iegor Benzyk Oct 19 '16 at 15:34

1 Answers1

0

I. Use ViewChild to specify concrete datepicker element and then setCallback in afterViewInit lifecycle method.

import {Component, ViewChild} from 'angular2/angular2';

@Component({
  selector: 'datepicker'
  // ...
})
export class Datepicker {
  // ...
}

@Component({
  selector: 'modal',
  directives: [NgIf, Datepicker, FORM_DIRECTIVES],
  // ...
})
export class Modal {
  //...
  @ViewChild('dp') datepicker : Datepicker;

  afterViewInit() {
    this.datepicker.setCallback(function(selectedDate : Date){
      console.log('Date: ' + selectedDate);
    });
  }
}

and template is:

<form action="#">
    // ...
    <datepicker #dp callback="selectDate" [(ng-model)]="datepicker"/>
    // ...
</form>

II. this inside onSelect function doesn't refer to the datepicker object. To fix it you have three options:

  1. Use bind method to change context of function execution:
export class Datepicker {
  // ...
  constructor() {
    $('.datepicker').datepicker({
      // ...
      onSelect: function(selectedDate) {
        console.log(this.callback);
      }.bind(this)
    });
  }
}
  1. Initialize var self = this outside of the onSelect callback and then use self inside it.
export class Datepicker {
  // ...
  constructor() {
    var self = this;
    $('.datepicker').datepicker({
      // ...
      onSelect: function(selectedDate) {
        console.log(self.callback);
      }
    });
  }
}
  1. Use arrow functions if you're using ES6:
export class Datepicker {
  // ...
  constructor() {
    $('.datepicker').datepicker({
      // ...
      onSelect: (selectedDate) => {
        console.log(this.callback);
      }
    });
  }
}
alexpods
  • 47,475
  • 10
  • 100
  • 94