【问题标题】:Passing data to child component via @Input is not triggering ngOnChanges and data is not being passed通过@Input 将数据传递给子组件不会触发 ngOnChanges 并且数据不会被传递
【发布时间】:2020-07-04 21:03:27
【问题描述】:

我正在尝试将数据从父组件传递到子组件。在我升级到 Angular 9 之前,相同的代码可以完美运行,我什至没有更改这部分代码中的任何内容。

这里是父组件的html模板:

<tk-dynamic-form-builder [queryableFields]="['something' , 'somethingElse']" [fieldsData]="fieldsData"></tk-dynamic-form-builder>
<button type="button" (click)="reset()" class="reset-button" aria-label="Search" [disabled]="loading">
    <span *ngIf="!loading">Reset</span>
</button>
<button type="button" (click)="search()" class="submit-button" aria-label="Search" [disabled]="loading">
    <span *ngIf="!loading">Search</span>
    <span *ngIf="loading">Searching... <i class='fas fa-spinner fa-pulse'></i></span>
</button>

这里是子组件相关的ts代码:

@Component({
    selector: 'tk-dynamic-form-builder',
    templateUrl: './dynamic-form-builder.component.html',
    styleUrls: ['./dynamic-form-builder.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicFormBuilderComponent implements OnInit, OnChanges {

    @Input() queryableFields: any[];

    dateFormat: string;
    public myForm: FormGroup;
    public numberOfRows: number;
    public richTextFields: any[];




    formFields: any[] = [];        // is the array of fields objects
    formBuilderParameters: any;    // parameters given to formbuilder.group
    formFieldIds: string[] = [];   // is an array that represents only the formFieldIds
    numberOfColumns: number;
    @Input() fieldsData: any[];    // is the data in the form fields which gets presented on update
    @Input() isViewMode = false;

    constructor(private dateFormatService: DateFormatService,
        private fb: FormBuilder,
        private http: HttpClient,
        private main: MainService,
        private store: Store<DynamicProgramLibState>) {

    }

    ngOnInit(): void {
        console.log("dynamic form builder initiated");
        this.store.pipe(select('loginState', 'formats')).subscribe(data => {
            this.dateFormat = data.dateFormat;
        });



    }

    ngOnChanges(): void {

        console.log("ngOnChanges Triggered");
        if (this.queryableFields) {
        //etc...
    }

    }

}

应用程序得到服务并且运行时没有错误,但子组件中的 ngOnChanges 从未被触发一次,而在升级到 Angular 9 之前,相同的代码曾经可以工作。 还有一点需要注意的是,这种传递数据的方法在整个项目中都不起作用,而不仅仅是在这个代码示例中。

任何建议或建议将不胜感激

【问题讨论】:

  • 你能创建一个我们可以调试的jsfiddle或codepen吗?
  • 很抱歉,子组件太大,其状态取决于ngrx 存储和外部因素。我已经在一个虚拟项目中简化了代码并且它有效。所以它不仅仅在这个项目的范围内工作。所以我希望有人能给我在哪里看的想法。 (在我需要配置的一些配置文件中)
  • 如果您简化了复杂性并且无法重现问题,则意味着问题在左侧

标签: javascript angular typescript ivy angular9


【解决方案1】:

这很奇怪,它以前是如何工作的,但现在不是。

我还看到你有changeDetection: ChangeDetectionStrategy.OnPush,这改变了默认值。

无论是Default 还是OnPush,只要您更改queryableFieldsfieldsData,就在您的父函数中不可变地更改它们。基本上,更改引用类型(数组或对象)在内存中的地址位置以进行更改检测。

所以在你的父组件中,每当queryableFields 发生变化时:

this.queryableFields = [...this.queryableFields, newValueHere];
// OR map for transformation
this.queryableFields = this.queryableFields.map(....); // map for a new reference
// OR filter for reduction
this.queryableFields = this.queryableFields.filter(....); // filter for a new reference

fieldsData 也是如此。

【讨论】:

  • 修复实际上非常简单......这段代码在一个角度库中。我建立图书馆的方式导致了这种故障。显然在 Angular 9 项目中,您必须在构建时将 --prod 标志添加到 ng 构建以使用 View 引擎。以前的版本不是这种情况
猜你喜欢
  • 2021-10-17
  • 2019-11-13
  • 2018-12-24
  • 2019-09-29
  • 2021-07-18
  • 2021-11-18
  • 2020-03-07
  • 2021-10-04
  • 2020-11-05
相关资源
最近更新 更多