Angular 5 pass ngModel through components

11,047

Solution 1

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.

Solution 2

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) => {};
    }
Share:
11,047
Gargoyle
Author by

Gargoyle

I run Gargoyle Software, LLC. It's a one-man software shop focused on custom iOS applications, and every once and a while a smallish mac application, based on what my customers need.

Updated on June 25, 2022

Comments

  • Gargoyle
    Gargoyle almost 2 years

    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.

  • mariomol
    mariomol over 5 years
    Hi.. i'm getting this, No provider for DecoratorFactory , you know why?
  • Antonio de la mata
    Antonio de la mata over 5 years
    Try to reinstall node_modules, you dont must to have problems. Or stay to sure that you are write well code.
  • Robert
    Robert over 4 years
    If you get "no provider for decoratorfactory" you should replace Component with the name of you Component in the useExisting property of the provider.