Reputation: 6167
I have a function that I need to run after this.value
is set in my component. I tried using the lifecycle hook ngAfterContentInit()
but this.value
is either null or an empty string at that point.
I'm referencing my component like:
<add-select name="address" [options]="knownAddresses" [(ngModel)]="user.address"></add-select>
And my component looks like
const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AddSelect),
multi: true
};
@Component({
selector: 'add-select',
templateUrl: 'build/components/add-select/add-select.html',
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class AddSelect implements ControlValueAccessor {
@Input() options: any[];
// * NEED THIS TO RUN AFTER this.value IS CURRENT WHICH IS PASSED IN VIA ngModel
private syncModelAndOptions() {
if (this.options && this.value) {
const modelOption = _.find(this.options, option => {
return item == this.value || (option._id && this.value._id && option._id === this.value._id);
});
if (modelOption) {
this.value = modelOption;
} else {
this.options.push(this.value);
}
}
}
//get accessor
get value(): any {
...
};
//set accessor including call the onchange callback
set value(v: any) {
...
}
//From ControlValueAccessor interface
writeValue(value: any) {
...
}
//From ControlValueAccessor interface
registerOnChange(fn: any) {
...
}
//From ControlValueAccessor interface
registerOnTouched(fn: any) {
...
}
Upvotes: 4
Views: 2666
Reputation: 6244
The reason why you implement the ControlValueAccessor
interface is so that your component would play nicely with Angular forms (both template-driven and reactive).
In template-driven forms (that's basically when you use ngModel
), an update to ngModel
eventually triggers a call to ControlValueAccessor.writeValue
, which is supposed to know how to update the underlying form controls.
So a surefire way to run something as soon as this.value
is set by the framework (i.e. ngModel
) is to call it from within writeValue
.
Upvotes: 1
Reputation: 957
Maybe using NgModel this way would help you. Inside your Component:
import { NgModel } from '@angular/forms';
/*...*/
constructor(ngModel: NgModel) {
ngModel.valueChanges.subscribe(() => {
console.log('ngModel set')
});
}
Upvotes: 0
Reputation: 1120
You can use AfterViewChecked lifecycle to get the ngModel when it HAS an actual value. If you really want to use lifecycle hooks.
https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#afterview
But... You should use ngModelChange as it Is an ngModel event.
https://angular.io/docs/ts/latest/guide/forms.html (search for ngModelChange)
Upvotes: 2