1

I have an Angular2 Directive which sets the maxDate of my DatePicker like this.

@Directive({
    selector: '[maxDate]'
})

export class MaxDateDirective {
    private domElement: any;
    @Input() set maxDate(max: any) {
        if (max) {
            $(this.domElement).data("DateTimePicker").maxDate(max);
        }
    }

    constructor(private element: ElementRef, private renderer: Renderer) {
        this.domElement = element.nativeElement;
    }
}

In my component I've dateFrom and dateTo like this.

                    <div class="col-md-3">
                        <div class="form-group">
                            <label class="label-control">{{'START_DATE' | translate}}</label>
                            <input id="owner_start_date" name="owner_start_date" type="text" class="form-control datepicker" [(ngModel)]="filters.lastWeek"
                                [maxDate]="filters.today" />
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="form-group">
                            <label class="label-control">{{'END_DATE' | translate}}</label>
                            <input id="owner_end_date" name="owner_end_date" type="text" class="form-control datepicker" [(ngModel)]="filters.today"
                            />
                        </div>
                    </div>

So, my fromDate picker has this [maxDate]="filters.today", which is bind to the [(ngModel)]="filters.today" of the toDate picker, but my @Input() set maxDate(max: any)is only triggering once. How can I check for updates on the model in the component from inside the Directive? I don't want to add code to the component, the Directive should be in charge of that logic, like the $watch in Angular1.

Alexander Staroselsky
  • 37,209
  • 15
  • 79
  • 91
MarBVI
  • 811
  • 2
  • 12
  • 34

1 Answers1

1

You could utilize the Angular lifecycle hook OnChanges within the MaxDateDirective that would allow you to "watch" for changes to the @Input() set maxDate(max: any) and react to them as needed, such as executing maxDate() with the new max date value. You would hook into OnChanges like this:

@Directive({
    selector: '[maxDate]'
})

export class MaxDateDirective implements OnChanges {
    private domElement: any;

    @Input() set maxDate(max: any) {
        if (max) {
            $(this.domElement).data("DateTimePicker").maxDate(max);
        }
    }

    constructor(private element: ElementRef, private renderer: Renderer) {
        this.domElement = element.nativeElement;
    }

    ngOnChanges(changes: SimpleChanges) {
        $(this.domElement).data("DateTimePicker").maxDate(changes.maxDate.currentValue);
    }
}

The object passed to the ngOnChanges() provides additional values that you could utilize such as previous value.

Here is a Plunker demonstrating at a simple level how that would look.

Hopefully that helps!

Alexander Staroselsky
  • 37,209
  • 15
  • 79
  • 91
  • I've tried this, but the ngOnChanges is never triggering when I select a new value in the toDate picker...it's like the [maxDate]="filters.today" is not looking at the filters.today changes – MarBVI Jul 10 '17 at 18:13
  • If you put {{filters.today}} on the page, do you see the interpolated value change when you select a different date? – Alexander Staroselsky Jul 10 '17 at 18:32
  • Yeah...the problem is that my datepicker isn't updating my ngModel. As soon as I fix it, I'll let you know. Thanks! – MarBVI Jul 10 '17 at 18:34
  • You could try lifecycle hook `DoCheck` to try detect the changes and selectively execute the jQuery DatePicker functionality and/or try flattening `filters.today` to just a separate class property `today` which should hopefully help with the change detection. – Alexander Staroselsky Jul 10 '17 at 18:56
  • This is how I fix it. Thank you for your time! https://stackoverflow.com/questions/36087762/how-to-detect-bootstrap-datetimepicker-change-events-within-angular2 – MarBVI Jul 10 '17 at 19:07