Nachfolgend ein paar Code-Schnippsel zur Erstellung einer Angular 4 Komponente mit In- und Output. Innerhalb der Komponente werden Bausteine von primeNg 4.1.x benutzt. In diesem Beispiel wird eine Komponente erstellt, die es ermöglicht ein Start und Endmonat (+Jahr) zu wählen.

Die Komponente kann dann wie folgt eingebunden werden:

<month-picker [(startTime)]="myStartTimeDate" [(endTime)]="myEndTimeDate" [appendTo]="body"></month-picker>

Benötigte Dateien

  1. Modulbeschreibung: month-picker.module.ts
  2. Frontend Businesslogik: month-picker.ts
  3. HTML5 Layout: month-picker.html

month-picker.module.ts

import {NgModule} from "@angular/core";
import {CommonModule} from "@angular/common";
import {FormsModule} from "@angular/forms";
import {MonthPickerComponent} from "./month-picker";
import {DropdownModule} from "primeng/components/dropdown/dropdown";

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    DropdownModule
  ],
  declarations: [
    MonthPickerComponent
  ],
  exports: [
    MonthPickerComponent
  ]
})
export class MonthPickerModule {
}

month-picker.ts

import {AfterViewInit, Component, Input, OnInit, Output, EventEmitter} from "@angular/core";
import {SelectItem} from "primeng/components/common/selectitem";

@Component({
  selector: 'month-picker',
  moduleId: module.id,
  templateUrl: 'month-picker.html',
})
export class MonthPickerComponent implements OnInit, AfterViewInit {

  /** for primeNg binding only */
  public selectedStartMonth: Date;
  public selectedEndMonth: Date;

  /** used for smarter impl */
  private _selectedStartMonth: SelectItem;
  private _selectedEndMonth: SelectItem;

  public startMonths: SelectItem[] = [];
  public endMonths: SelectItem[] = [];

  @Input() startTime: Date;
  @Output() startTimeChange = new EventEmitter();

  @Input() endTime: Date;
  @Output() endTimeChange = new EventEmitter();

  @Input() appendTo: any = null;

  ngOnInit() {
    this._initStartMonths();
  }

  ngAfterViewInit(): void {
    if(this.startTime != null){
      let month: SelectItem = this._createOneMonthObjectFromDate(this.startTime);
      this._selectedStartMonth = month;
    }

    if(this.endTime != null && this.endTime != null){
      let month: SelectItem = this._createOneMonthObjectFromDate(this.endTime);
      this._selectedEndMonth = month;
    }
  }

  public onStartMonthChange(event: any): void{
    let newStartMonth: SelectItem = this.startMonths.find((x: SelectItem) => x.value === event.value);
    if(newStartMonth != null && newStartMonth.value != null){
      this._selectedStartMonth = newStartMonth;
      this._initEndMonths();
      this.startTimeChange.emit(this._selectedStartMonth.value);
    }
  }

  public onEndMonthChange(event: any): void{
    let newEndMonth: SelectItem = this.endMonths.find((x: SelectItem) => x.value === event.value);
    if(newEndMonth != null && newEndMonth.value != null){
      this._selectedEndMonth = newEndMonth;
      this.endTimeChange.emit(this._selectedEndMonth.value);
    }
  }

  private _initStartMonths(): void{

    // first entry: null
    this.startMonths.push({label:"-- none --", value: null});

    let startDate: Date = new Date();
    startDate.setUTCFullYear(2016, 0, 1); // we never go before Jan 2016!
    startDate.setUTCHours(0, 0, 0, 0);

    let now: Date = new Date();
    now.setDate(0); // last day of last month (current month is not a valid selection here!)

    while(startDate < now){
      let month: SelectItem = this._createOneMonthObjectFromDate(startDate);
      this.startMonths.push(month);

      startDate.setUTCMonth(startDate.getUTCMonth() + 1);
    }
  }

  private _initEndMonths(): void{
    this.endMonths = [];
    // first entry: null
    this.endMonths.push({label:"-- none --", value: null});

    let endDate: Date = new Date(this._selectedStartMonth.value.getTime());
    endDate.setUTCDate(26);

    let now: Date = new Date();

    while(endDate < now){
      let month: SelectItem = this._createOneMonthObjectFromDate(endDate);
      this.endMonths.push(month);

      endDate.setUTCMonth(endDate.getUTCMonth() + 1);
    }
  }

  private _createOneMonthObjectFromDate(endDate: Date): SelectItem {
    let currDate: Date = new Date(endDate.getTime());
    return {label: this.labelFromDate(currDate), value: currDate};
  }

  public labelFromDate(someDate: Date): string {
    return someDate.getUTCFullYear() + "-" + this._pad(someDate.getUTCMonth() + 1, 2);
  }

  private _pad(num, size) {
    let s: string = "00" + num;
    return s.substr(s.length - size);
  }
}

month-picker.html

<div class="ui-month-picker">
  <span>from </span>
  <p-dropdown [options]="startMonths" [(ngModel)]="selectedStartMonth" (onChange)="onStartMonthChange($event)"
              [appendTo]="appendTo" [style]="{'width':'100px'}" class="start-months-dropdown">
  </p-dropdown>

  <span> to </span>
  <p-dropdown [options]="endMonths" [(ngModel)]="selectedEndMonth" (onChange)="onEndMonthChange($event)"
              [appendTo]="appendTo" [style]="{'width':'100px'}" [disabled]="selectedStartMonth == null"
              class="end-months-dropdown">
  </p-dropdown>
</div>