在Angular2中,我如何订阅自定义组件事件?

时间:2016-09-07 05:49:07

标签: angular rxjs

我有一个组件,这是一个填充办公室的选择下拉列表:

@Component({
  selector: 'office-dropdown',
  template: `
    <select [(ngModel)]="selectedOffice" (ngModelChange)="handleChange()" class="form-control">
      <option value="0">Välj kontor</option>
      <option *ngFor="let office of offices$ | async" [ngValue]="office">
        {{office.officeName}}
      </option>
    </select>
    `
})
export class OfficeDropdownComponent implements OnInit {
  @Input() filters = {};
  @Output() myCustomOnChange = new EventEmitter();
  offices$: Observable<Office[]>;
  selectedOffice = 0;

  constructor(private apiService: ApiService) {}

  ngOnInit() {
    this.offices$ = this.apiService.doRequest()
      .map(response => response.offices);
  }

  handleChange() {
    this.myCustomOnChange.emit(this.selectedOffice);
  }
}

在下面的组件中,我正在使用该办公室下拉列表,它工作正常,但我想将一个可观察的流连接到其自定义myCustomOnChange事件并订阅它:

@Component({
  selector: 'admin-select-employee',
  template: `
      <office-dropdown #officeDropDown (myCustomOnChange)="handleOffice($event)"></office-dropdown>
  `
})
export class AdminSelectEmployeeComponent implements OnInit, OnDestroy, AfterViewInit {
  @ViewChild('officeDropDown') officeDropDown;
  officeDropDown$: Observable<any>;

  ngAfterViewInit() {
    this.officeDropDown$ = Observable
      .fromEvent(this.officeDropDown, 'myCustomOnChange');

    this.officeDropDown$.subscribe((event) => {
      console.log(event); // This never gets logged
    });
  }

  handleOffice(office){
     console.log(office); // This works
  }

但ngAfterViewInit中的console.log永远不会被记录。

任何想法为什么?

编辑我已经删除了很多周围的代码,只是为了说明我遇到问题的地方,而不是用不必要的代码膨胀我的例子。实际上,第二个组件充满了更多的html / ts。

1 个答案:

答案 0 :(得分:2)

$event只是发出的值,而不是observable,而@Output()不会触发.fromEvent()所针对的DOM事件。

我会用

  officeDropDown$: Observable<any>;
  private officeDropDown = new Subject();

  constructor() {
    this.officeDropDown$ = this.officeDropDown.asObservable();
    this.officeDropDown$.subscribe((event) => {
      console.log(event); // This never gets logged
    });
  }

  handleOffice(office){
    console.log(office); // This works
    this.officeDropDown.next(office); 
  }