4

I have component with input:

<my-input *ngIf='filter.type === checkType.INPUT_TEXT' [filter]='filter'></my-input>

export class MyInputComponent{
  @Input() filter: any;
}

Template of MyInputComponent

<input name="name" [(ngModel)]="filter.input">

I want to set filter input inside and have influence on outer Component object.

How to pass filter object into MyInputComponent to achieve 2 way data binding?

I want to achIeve something like [(ngModel)]="filter.value" but working between Components

Other posts here about 2-way data binding does'nt answer my questions.

Edit:

After using extends DefaultValueAccessor in my MyInputComponent my parent component input disapears without any error.

import { Component, Input, OnInit, Provider, forwardRef } from '@angular/core';
import { FORM_DIRECTIVES, NG_VALUE_ACCESSOR, DefaultValueAccessor } from '@angular/common';

@Component({
  moduleId: module.id,
  selector: 'my-input',
  directives: [FORM_DIRECTIVES],
  host: { '(keyup)': 'doOnChange($event.target)' },
  templateUrl: '<input name="name" [(ngModel)]="filter.input">'
})

export class MyInputComponent extends DefaultValueAccessor {
  @Input() filter: any;

  onChange = (_) => {};
  onTouched = () => {};

  writeValue(filter:any):void {
    if (filter !== null) {
      super.writeValue(filter.toString());
    }
  }
  doOnChange(filter) {
    this.onChange(filter);
  }
}

const MY_VALUE_ACCESSOR = new Provider(
  NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => MyInputComponent), multi: true});
Adam Michalski
  • 1,722
  • 1
  • 17
  • 38

1 Answers1

2

You need to implement a custom value accessor for this. Here is a sample of this:

const MY_VALUE_ACCESSOR = new Provider(
  NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => MyInputComponent), multi: true});

@Component({
  (...)
  providers: [ MY_VALUE_ACCESSOR ]
})
export class MyInputComponent extends DefaultValueAccessor {
  onChange = (_) => {};
  onTouched = () => {};

  writeValue(value:any):void {
    if (value!=null) {
      super.writeValue(value.toString());
    }
  }

  // call when your internal input is updated
  doOnChange(val) {
    this.onChange(val);
  }
}

For more details, see this article (section "NgModel-compatible component"):

See also this question:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • I will check it, my experience is low so, is this the best way to set value field of object passed like this or better is to go out of all Comonents up in hierarchy and set it by passing index and value by method better practice, or is there any other way to set this value? – Adam Michalski Jul 01 '16 at 04:41