简体   繁体   English

无法在组件Angular 8中绑定动态数据

[英]Cannot Bind Dynamic Data in Component Angular 8

Error when component loading dynamic 动态加载组件时出错

DynamicBuilderComponent.ngfactory.js:198 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. DynamicBuilderComponent.ngfactory.js:198错误错误:ExpressionChangedAfterItHasBeenCheckedError:检查表达式后,表达式已更改。 Previous value: 'ng-pristine: true'. 以前的值:'ng-pristine:true'。 Current value: 'ng-pristine: false'. 当前值:“ ng-pristine:false”。

Problem 问题

    after binding json in select2data to select2 component Angular throw exception.

component code 组件代码

           @Component({
              changeDetection: ChangeDetectionStrategy.OnPush,
              selector: 'select2',

Imported changeDetection in component. 在组件中导入了changeDetection。

              template: `
                  <div [formGroup]="form">

                    <ng-container>
                        <ng-select2
                          [data]="select2data"
                          [options]="options"
                          [width]="500"

                          [formControlName]="field.code"
                          (keyup)="changed($event.target.value)">
                        </ng-select2>
                    </ng-container>

                  </div>`
            })

select2 component class select2组件类

            export class Select2Component implements OnInit {
              @Input() field: any = {};
              @Input() form: FormGroup;
              public exampleData: Array<Select2OptionData>;
              public options: Options;
              public value: string[];
              select2data: any;
              public selected: string;

              constructor(public cl: Services,private cd: ChangeDetectorRef) {
                this.options = {
                  width: '258',
                  multiple: true,
                  tags: false
                };
              }

Problem Area After Binding subscribe data in ng select2 component 绑定后的问题区域在ng select2组件中订阅数据

              changed(search: any) {

               //call service pass search text to service
                return this.cl.searchFunc(search).subscribe(
                  res1 => 
                          this.select2data = res1.data;
                              this.cd.markForCheck(); // marks path
                      }
                    }
                  },
                  error => {
                    console.log('error  = ', error);
                  });
              }

            }

i tried to print this.select2data in console.log its return me json. 我试图在console.log中打印this.select2data它返回我json。

Vendor.js Vendor.js

            function expressionChangedAfterItHasBeenCheckedError(context, oldValue, currValue, isFirstCheck) {
                var msg = "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '" + oldValue + "'. Current value: '" + currValue + "'.";
                if (isFirstCheck) {
                    msg +=
                        " It seems like the view has been created after its parent and its children have been dirty checked." +
                            " Has it been created in a change detection hook ?";
                }
                return viewDebugError(msg, context);
            }

Great Article 好文章

https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

Reference 参考

Expression ___ has changed after it was checked 表达式___在检查后已更改

  • any suggestion is most welcome. 任何建议都是最欢迎的。

I believe that you put your component select2 inside another component which contains a form which you then pass to select2 for create another <form> tag, is that correct? 我相信您将组件select2放在另一个包含表单的组件内,然后将其传递给select2以创建另一个<form>标记,对吗? I mean do you have something like that? 我的意思是你有那样的东西吗?

<form [formGroup]="form">
    <!-- Some code -->
    <select2 [field]="something" [form]="form"></select2>
</form>

If so, then your select2 component SHOULD NOT contain re-declaration of form, it should not contain anything related to forms at all. 如果是这样,那么您的select2组件不应包含表单的重新声明,它根本不应该包含与表单相关的任何内容。 It should be a form control. 它应该是一个表单控件。 Please read a post by Netanel Basal on how to create custom form controls. 请仔细阅读如何创建自定义窗体控件通过Netanel基础。 You will need to create ControlValueAccessor for your select2 and wire it up to Angular forms through a custom provider. 您将需要为select2创建ControlValueAccessor ,然后通过自定义提供程序将其连接到Angular表单。

The issue you're facing is that since you include form object twice in the DOM data changes are propagated twice as well and you run into issues. 您面临的问题是,由于您在DOM中两次包含了form对象,因此数据更改也被传播了两次,并且遇到了问题。 There should be only one reference to a specific instance of FormGroup in your templates. 模板中应该仅对FormGroup的特定实例有一个引用。

Solution that worked 有效的解决方案

         @Component({
          changeDetection: ChangeDetectionStrategy.OnPush,
          selector: 'select2',
          export class Select2Component implements OnInit {
            constructor(public cl: Services,private cd: ChangeDetectorRef) {
            this.options = {
              width: '258',
              multiple: true,
              tags: false
            };
          }

Binding function 装订功能

 changed(search: any) {

           //call service pass search text to service
            return this.cl.searchFunc(search).subscribe(
              res1 => 
                      this.select2data = res1.data;
                      this.cd.markForCheck(); // marks path
                     this.cd.detectChanges();
                  }
                }
              },
              error => {
                console.log('error  = ', error);
              });
          }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM