Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
553 views
in Technique[技术] by (71.8m points)

javascript - ERROR in : No provider for NgControl Angular AOT

I am trying to implement a custom ControlValueAccessor as Kara Erickson recommended on last Angular Connect https://youtu.be/CD_t3m2WMM8?t=20m22s . To pass the validity state from the parent component to the child one.

app.component.html:

<app-country-select ngModel="model" name="country-select"></app-country-select>

country-select.component.html:

<select [formControl]="controlDir.control" #select placeholder="Country" i18n-placeholder (click)="onTouched()"
        (change)="onChange($event.value)" [required]="required">
  <option value="at">Austria</option>
  <option value="au">Australia</option>
</select>

country-select.component.ts:

@Component({
    selector: 'app-country-select',
    templateUrl: './country-select.component.html',
    styleUrls: ['./country-select.component.scss'],
})
export class CountrySelectComponent implements ControlValueAccessor {

    @Input() required = false;

    @ViewChild('select') select: HTMLSelectElement;

    onChange: (value: any) => void;
    onTouched: () => void;

    constructor(@Self() public controlDir: NgControl) {
      controlDir.valueAccessor = this;

    }
...
}

The full code lives here: https://github.com/maksymzav/ngcontrol .

The code works perfectly when running it in the JIT mode. I guess because in runtime it does know with which control it is used: NgModel, or FormControlName, or FormControlDirective. But when I run an AOT build with ng build --prod it fails with message

ERROR in : No provider for NgControl ("[ERROR ->]<app-country-select></app-country-select>")

Does anyone know how to make this build successful? Thank you.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can add @Optional() decorator to your controlDir.

A parameter metadata that marks a dependency as optional. Injector provides null if the dependency is not found.

In my case, that solved the "No provider" error and I was able to successfully compile the project.

Example:

constructor(
  @Optional() // Add this decorator
  @Self()
  public controlDir: NgControl,
  private stripe: StripeService,
  private cd: ChangeDetectorRef
) {
  // Better to add some checks here since controlDir can be null
  if (controlDir) {
    controlDir.valueAccessor = this;
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...