1

I am trying to use ngOnChanges to create a search filter as the user types in letters into the input. Here is my code:

export class SearchComponent implements OnInit, OnChanges {
        @Input() search:string

         // trying to get this to run each time the input value changes
         public ngOnChanges(changes: any) {
            console.log(changes.search);
         }
}

@NgModule({
      imports: [MaterialModule, FlexLayoutModule, BrowserModule, FormsModule]
      // declarations, providers, exports also defined here
 })

Input element in the component template:

// using Material Design Library
<input mdInput [search]="searchText" type="text" placeholder="Search"></input>

Or can I only use an @Input like this:

<search-component [search]="searchText"></searchComponent>

But then does searchText here bind to my controller?

The error I keep getting is "Can't bind to "search" since it isn't a know property of "input".

I had the understanding that the @Input decorator took care of that but clearly I am missing something here.

Note: I did add the filter using (ngModelChange) and binding to the [(ngModel)] value in my controller..works fine. But it sounds like using ngOnChanges is the best way to do this so I'm trying to understand how to make it work. Thanks

2 Answers 2

1

@Input() allows you to bind an expression to the property marked with it, so declaring search as an input property allows you to use property binding on that property. So to use it, simply do this in some component's template you want to place your SearchComponent in, e.g.

<app-root>
    <search-component [search]='"dummy text"'></searchComponent>
</app-root>

You can't do a property binding on the search property on input element because HTMLInputElement interface has no such member, hence the exception. You can only do property bindings on properties that exist on that specific element you are binding to

Sign up to request clarification or add additional context in comments.

4 Comments

OK makes sense with the input element property. So if I add it to the component element as you have done..does that then automatically find any input elements inside my template for <search-component>, and pick up the changes through ngOnChanges? It's not with the update so I'm still missing something. Or how does that pick up changes on the input element in my template? And how can I bind to the text value on the input as the user types into it..i.e. how can I two way bind to dummy text inside my controller - [(search)]='dummyText', and controller: "this.dummyText"..is that correct? Thanks
<search-component>'s template has a list of data coming from a service and then using *ngFor to display it on the page so its not just and input element and that's it..there is an input at the top of the template where the user can filter..which is why I'm wondering how exactly the changes would get picked up on the specific input element in the template...
if you want 2 way data-binding then in your SearchComponent template, do this <input mdInput [(ngModel)]="search" type="text" placeholder="Search" name="search-term"/>, so if the user enters some text, the input.value changes, it will update your search property and if your search property changes, the text input box will show the new value too, that's 2 way data flow for you. Note that, in order to use angular form, each element must have a name attribute set on it
This is an excellent tutorial on angular form I highly recommend you reading angular.io/docs/ts/latest/guide/forms.html
0

I am not sure, but I have something similar in my code

@Directive({
  selector: '[contenteditableModel]',
  host: {
    '(blur)': 'onEdit()',
    '(keyup)': 'onEdit()'
  }

})

export class ContentEditableDirective implements OnChanges {
@Input('contenteditableModel') model:any;
@Output('contenteditableModelChange') update = new EventEmitter();

constructor(private elementRef:ElementRef) {

}


ngOnChanges(changes:SimpleChanges):void {

    if (changes.model.firstChange == true) {
        this.refreshView();
    }

}

public onEdit() {

    let value:string = this.elementRef.nativeElement.innerHTML;
    this.update.emit(value);

}

public refreshView():void {

    this.elementRef.nativeElement.innerHTML = this.model;
}

}

As I understand, I am not actually use ngOnChanges function, instead of it, I bind my onEdit on keyup and trigger change event through EventEmmiter()

I hope my code will help you find solution

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.