2

I am wanting to update an @Input property from a child and for the changes to take effect on the parent.

Parent TS (document-details):

export class DocumentDetailsComponent implements OnInit {
  view: string = 'editor';
}

Parent HTML (document-details):

<document-content [(view)]="view" ></document-content>

Child TS (document-content):

export class DocumentContentComponent implements OnInit, OnChanges {

  @Input() view: string;

  ngOnChanges(changes: SimpleChanges) {
    if (changes.version) {
      this.view = 'editor';
    } 
  }
}

When the view property inside the child component gets set top 'editor' it doesn't seem to reflect these changes inside the parent component.

I know I could use an @Ouput event emitter but I feel like this should work fine.

6
  • EventEmitter and @Output it works perfectly, but there is other solutions to share data like ngrx store or observables with subjects buy using subject next function Commented Mar 17, 2018 at 13:39
  • @FatehMohamed Shouldn't the value inside the parent change when the child Input value changes? Commented Mar 17, 2018 at 13:53
  • no, you need EventEmitter and @Output to achieve that and if you have a big application with a big data to share between components i advice you to use redux store for that Commented Mar 17, 2018 at 13:55
  • You always can make a custom form control implements ControlValueAccessor Commented Mar 17, 2018 at 14:00
  • No it's shouldn't work. it's behave is correct because you bind the view variable in the child component with the one in the parent component. so the logic is when the parent variable change the child variable change too and not vice verse Commented Mar 17, 2018 at 14:07

2 Answers 2

3

When angular bootstraps it builds a component tree.Component

A component has input and output properties, which can be defined in the component decorator or using property decorators.

Data flows into a component via @input properties(Parent to child ). Data flows out of a component via @output(child to parent) properties.

with @input property data flows down the tree.It doesn't flow upwards.

if you want data flow in the opposite direction i.e Upwards you need to use @Output decorator and Event emitter.

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

Comments

0

If you want changes from an @Input to affect the parent that means you want your @Input to also be an @Output, this is called two-way binding to which you can find the documentation here.

But in summary what happens is that in angular this:

<document-content [(view)]="view" ></document-content>

Is syntactic sugar for this:

<document-content [view]="view" (viewChange)="view=$event" ></document-content>

So in order for your code to work you need to create the viewChange output and call emit() whenever your code changes the view property.

@Input() view: string;
@Output() viewChange = new EventEmitter<string>();

ngOnChanges(changes: SimpleChanges) {
  if (changes.version) {
    this.view = 'editor';
    this.viewChange.emit(this.view);
  } 
}

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.