Skip to content

updated Creating a Custom Form Field doc ngControl section #9855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 9, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 29 additions & 9 deletions guides/creating-a-custom-form-field-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,23 +157,43 @@ private _placeholder: string;

#### `ngControl`

This property allows the form field control to specify the `@angular/forms` control that is bound to
this component. Since we haven't set up our component to act as a `ControlValueAccessor`, we'll just
set this to `null` in our component. In any real component, you would probably want to implement
`ControlValueAccessor` so that your component can work with `formControl` and `ngModel`.
This property allows the form field control to specify the `@angular/forms` control that is bound to this component. Since we haven't set up our component to act as a `ControlValueAccessor`, we'll just set this to `null` in our component.

```ts
ngControl = null;
ngControl: NgControl = null;
```

If you did implement `ControlValueAccessor`, you could simply inject the `NgControl` and make it
publicly available. (For additional information about `ControlValueAccessor` see the
[API docs](https://angular.io/api/forms/ControlValueAccessor).)
It is likely you will want to implement `ControlValueAccessor` so that your component can work with `formControl` and `ngModel`. If you do implement `ControlValueAccessor` you will need to get a reference to the `NgControl` associated with your control and make it publicly available.

The easy way is to add it as a public property to your constructor and let dependency injection handle it:

```ts
constructor(..., @Optional() @Self() public ngControl: NgControl) { ... }
constructor(
...,
@Optional() @Self() public ngControl: NgControl,
...,
) { }
```

Note that if your component implements `ControlValueAccessor`, it may already be set up to provide `NG_VALUE_ACCESSOR` (in the `providers` part of the component's decorator, or possibly in a module declaration). If so you may get a *cannot instantiate cyclic dependency* error.

To resolve this, remove the `NG_VALUE_ACCESSOR` provider and instead set the value accessor directly:

```ts
constructor(
...,
@Optional() @Self() public ngControl: NgControl,
...,
) {
// Setting the value accessor directly (instead of using
// the providers) to avoid running into a circular import.
if (this.ngControl != null) { this.ngControl.valueAccessor = this; }
}
```

For additional information about `ControlValueAccessor` see the [API docs](https://angular.io/api/forms/ControlValueAccessor).


#### `focused`

This property indicates whether or not the form field control should be considered to be in a
Expand Down