代码之家  ›  专栏  ›  技术社区  ›  Ole

观察子组件中的@Output事件发射器?

  •  1
  • Ole  · 技术社区  · 1 年前

    应该如何使用/观察家长 @Output() 子组件中的事件发射器?

    For example in this demo 子组件使用 @Output onGreetingChange 这样地:

    <app-greeting [greeting]="onGreetingChange | async"></app-greeting>
    

    如果 onGreetingChange 在中发射 AfterViewInit 生命周期挂钩。

      ngAfterViewInit() {
        this.onGreetingChange.emit('Hola');
      }
    

    然而,这会产生 ExpressionChangedAfterItHasBeenCheckedError 错误

    有没有一种方法可以在不产生错误的情况下实现这一点?

    我试着在两个 constructor OnInit 。想法?

    2 回复  |  直到 1 年前
        1
  •  1
  •   Naren Murali    1 年前

    您可以触发 change detection 手动,使用 detectChanges()

    我的猜测是,由于这是一种非传统的改变 @Input 更改检测缺少更改,所以我们需要手动运行它!

      ngAfterViewInit() {
        this.onGreetingChange.emit('Hola');
        this.cdr.detectChanges();
      }
    

    stackblitz

        2
  •  0
  •   NgDaddy    1 年前

    你总是可以使用 BehaviorSubject 而不是 EventEmitter 。优点在于初始值。请参阅:

    https://stackblitz.com/edit/stackblitz-starters-bncmrb?file=src%2Fmain.ts

    主应用程序

    @Component({
      selector: 'app-root',
      imports: [AppChild, AppChildTwo, AsyncPipe],
      standalone: true,
      templateUrl: './app.component.html',
    })
    export class App implements OnInit, AfterViewInit {
      @Output()
      // onGreetingChange: EventEmitter<string> = new EventEmitter();
      onGreetingChange = new BehaviorSubject('Hola!!');
    
      greetingTwo!: string;
    
      constructor() {
        //    this.onGreetingChange.emit('Hola!!');
      }
    
      ngOnInit() {
        // this.onGreetingChange.emit('Hola!!');
      }
    
      ngAfterViewInit() {
        // this.onGreetingChange.emit('Hola');
      }
    }
    

    HTML

    <div><app-greeting [greeting]="onGreetingChange | async"></app-greeting></div>
    <div>
      <app-greeting-two (greetingTwo)="greetingTwo = $event"></app-greeting-two>
    </div>
    <h2>{{ greetingTwo }}</h2>
    

    儿童一

    @Component({
      selector: 'app-greeting',
      standalone: true,
      template: '<h1>{{ greeting }} Everyone!</h1>',
      changeDetection: ChangeDetectionStrategy.OnPush,
      encapsulation: ViewEncapsulation.None,
    })
    export class AppChild {
      @Input()
      greeting!: string | null;
    }
    

    第二个孩子

    @Component({
      selector: 'app-greeting-two',
      standalone: true,
      template: '<h1>AppChildTwo: {{ greetingTwo | async }} Everyone!</h1>',
      changeDetection: ChangeDetectionStrategy.OnPush,
      encapsulation: ViewEncapsulation.None,
      imports: [AsyncPipe],
    })
    export class AppChildTwo {
      @Output()
      greetingTwo = new BehaviorSubject('Initial greeting TWO');
    }
    
        3
  •  0
  •   Hussein AbdElaziz    1 年前

    最好使用 ChangeDetectionStrategy.OnPush 性能

    @Component({
      selector: 'app-root',
      imports: [AppChild, AsyncPipe],
      standalone: true,
      changeDetection: ChangeDetectionStrategy.OnPush,
      template: `
        <app-greeting [greeting]="onGreetingChange | async"></app-greeting>
      `,
    })
    export class App implements OnInit, AfterViewInit { 
      @Output()
      onGreetingChange = new EventEmitter<string>();
    
      ngAfterViewInit() {
        this.onGreetingChange.emit('Hola');
      }}
    

    代码示例 https://stackblitz.com/edit/stackblitz-starters-grepmj?file=src%2Fmain.ts