Angular: 使用一个方法来填充一个@Input值。

问题描述 投票:1回答:1

为什么该方法 getDayShifts(day) 在父组件的模板中,每次鼠标悬停在子组件上时都会被调用?

abstract.class.ts

export abstract class DayView implements OnInit, OnDestroy, OnChanges {

  public ngOnInit(): void {
    this.dl.shifts
        .pipe( 
            takeUntil(this.ngUnsubscribe),
            map( shifts => this.shifts = shifts),
            tap( shifts => this.filterShifts())
        )
        .subscribe();
  }

  public ngOnChanges(changes: SimpleChanges): void {
    this.filterShifts();
    this.afterChanges(changes);
    this.cdr.detectChanges();
  }

  public abstract afterChanges(changes: SimpleChanges)

  public getDayShifts( day: CalendarDay ): Array<Shift> {
    const s = this.views.getDayShifts(day.date, this.filteredShifts);
    return s;
  }

  /** ... */

}

parent.component.ts

@Component({
    selector: 'day-month-view',
    templateUrl: './day-month-view.component.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class DayMonthViewComponent extends DayView {
    public afterChanges(changes: SimpleChanges): void {}
}

parent.component.html

<div *ngFor="let week of weeks; index as _wi">
   <div *ngFor="let day of week; index as _di">

     <dropdown-btn
            [id]="'dd_'+_wi+'_'+_di"
            [isEnabled]="isEditable(day.date)"
            [options]="dayOptions"
THIS ONE => [objectData]="getDayShifts(day)"
            (selected)="onOptionClick($event)"><span class="day-date">{{day.date.getDate()}}</span></dropdown-btn>
     <shift-month
            [day]="day"
THIS ONE => [shifts]="getDayShifts(day)"></shift-month>
   </div>
</div>

child.component.ts

@Component({
    selector: 'shift-month',
    templateUrl: './shift-month.component.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class ShiftMonthComponent extends ShiftView {
    public afterInit() {
        const dayShifts = this.views.getDayShifts(this.day.date, this.shifts);
        this.filteredShifts = this.setViewMeta(dayShifts);
        this.cdr.markForCheck();
    }
}

孩子的抽象类.ts

export abstract class ShiftView implements OnInit, OnChanges, OnDestroy {

    public ngOnChanges(): void {
        this.afterInit();
    }

    public abstract afterInit()
}

会不会总是触发一个 @Input() 如果是一种方法?我有些迷茫。

javascript angular typescript angular-template angular-changedetection
1个回答
0
投票

是的,这种情况会发生,因为方法可以随时改变值,所以为了确保正确的值在那里,Angular会在每次重新渲染时调用它。这就是为什么在模板中调用方法是不好的做法。

不过如果你想做的话,还是可以在组件装饰器里面使用OnPush策略。但这样一来,你可能需要在某些地方手动触发变化检测。最好的办法是你能摆脱模板中的方法调用,而是传递一个简单的属性。

© www.soinside.com 2019 - 2024. All rights reserved.