3

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.

Gargoyle
  • 9,590
  • 16
  • 80
  • 145
  • Check [Implement two-way data binding for custom property](https://stackoverflow.com/q/52290322/387194) you only need to use `ngModel` as `@Input/@Output` name. – jcubic Mar 18 '19 at 14:53

2 Answers2

5

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) => {};
    }
  • 1
    Hi.. i'm getting this, No provider for DecoratorFactory , you know why? – mariomol Nov 29 '18 at 13:51
  • Try to reinstall node_modules, you dont must to have problems. Or stay to sure that you are write well code. – Antonio de la mata Dec 07 '18 at 09:03
  • 1
    If you get "no provider for decoratorfactory" you should replace Component with the name of you Component in the useExisting property of the provider. – Robert Nov 27 '19 at 12:20
3

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.

Jack Guy
  • 8,346
  • 8
  • 55
  • 86