2

I have a child component which gets an attribute value from the parent component using @Input directive. the problem is that two way data binding does not seem to work with this input attribute. any idea what could be a reason for that?

child component class

@Component({
  selector: 'app-edit-property',
  templateUrl: './edit-property.component.html',
  styleUrls: ['./edit-property.component.css']
})
export class EditPropertyComponent implements OnInit {

  @Input() property: any;

  constructor(
    private propertiesService: PropertiesService
  ) { }

  ngOnInit() {
  }

}

template

<input type="text" class="form-control" required name="title" [(ngModel)]="property.title" #title="ngModel">

parent component

<app-edit-property [property]='property'></app-edit-property>
4
  • Can you please share the code ? Commented Mar 21, 2019 at 18:45
  • There's no real 2-way binding in Angular. That was one of the pitfalls of Angular.js. There is a syntactic sugaring for combining attribute binding and event binding. I'm not sure what you tried to do since you didn't add any code. Commented Mar 21, 2019 at 18:46
  • I want to create a component to perform update/edit of an existing object, I created a child component and passed a copy of the object to it, but it seems that it is not a good way to do that, any suggestions for the best way to edit an object without navigating to a new component with a new call to the API to retrieve the data? Commented Mar 21, 2019 at 18:59
  • 1
    if property is an object, you needn't use @Output, see the simple example in stackblitz.com/edit/… Commented Mar 21, 2019 at 20:21

2 Answers 2

8

For the two way binding works, you must implement a @Output with the same name of the attribute with Change as a postfix like this:

 @Input() counter;
 @Output() counterChange = new EventEmitter();

in the html, you add [(counter)]="someValue" And you emit the new value like this:

 this.counterChange.emit(this.counterValue);

First you need make "counter" as getter/setter property like below and emit that event in setter -

 private _counter: any;
      get counter(): any {
        return this._counter;
      }

     @Input() set content(value: any) {
        this._counter = value;
        this.counterChange.emit(value);
        // *Event emitting should done here*
      }
    
      @Output() counterChange = new EventEmitter<any>();
Sign up to request clarification or add additional context in comments.

3 Comments

it's NOT necesary. You are using an object as input, so the "address of memory" of the object it's always the same, but the propertys can change, see my comment and my stackblitz
this is really cool, didn't realize this type of two way data binding two a child component was a thing. Thanks!
@Eliseo You're right, but you must be extra carefull. If the Input object is used in the whole application, all the components using this object will be refreshed when you update the Input object. That can result of lag in the application.
0

@Input directive is designed for one way binding. You only get value into the component using @Input. Use @Output directive to emit a value from the component so that the parent component receives the value.

2 Comments

no, it's not necesary (the reason is that you are using an object as @Input
this is right, Input & Output are supposed to be used as one way binding. In your case, since it is object(in shared code) it is working. What do you exactly mean by "two way data binding does not seem to work"? what you are trying to do in parent component with the property? i should work if you just want to render in template.

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.