Gargoyle
Gargoyle

Reputation: 10324

Angular 5 pass ngModel through components

I've created a simple component that wraps bootstrap's typeahead controller so it's configured the way I want for the app. The component has a public variable, selectedWorker that's the ngModel from the typeahead.

So now, when I use this component elsewhere, I'd want to do something like so:

<app-worker-lookup [(ngModel)]="foo"></app-worker-lookup>

And then have the foo variable of the caller be tied to the public variable of the lookup component that has the selected value. I'm not sure how to implement that.

Upvotes: 3

Views: 14204

Answers (2)

Antonio de la mata
Antonio de la mata

Reputation: 404

For can use ngModel in your Component your class must implement ControlValueAccesor and add the Component to the provide token

Component

    @Component({
    selector: 'component',
    templateUrl: '../component.html',
    styleUrls: ['../component.scss'],
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => Component),
            multi: true
        }
    ]
}) 
export class Component implements ControlValueAccessor {

        //
        // Now add ngModel property binding
        @Input() ngModel : NgModel;

        ....

        //
        // ControlValueAccessor implementation
        writeValue(value:any) {
           this.value = value;
        }

        registerOnChange(fn) {
            this.propagateChange = fn;
        }

        registerOnTouched(fn){
        }

        private propagateChange = (_:any) => {};
    }

Upvotes: 5

Jack Guy
Jack Guy

Reputation: 8523

In order to have ngModel available on a component, you'll need to implement the component as a custom form control. This should be relatively straightforward seeing as your component's form behavior will be the same as typeahead's.

Here's a nice article on how to do this, or a Stack Overflow answer if you prefer.

One thing to note is that in order to implement two-way binding correctly, you'll need to split up your typeahead component's [(ngModel)] attribute into [ngModel]="selectedWorker" (ngModelChange)="onChange($event)" so that you can call writeValue() in the onChange method.

Upvotes: 3

Related Questions