I am trying to remove Test2 value from an input decorator value from the change component. But not able to remove it. so how to get solution for this.
change component:
export class ChangeComponent implements OnInit {
@ViewChild('changeComponent') changeComponent: TableComponent;
constructor() {}
ngOnInit() {}
changeName() {
this.changeComponent.names.pop('Test2');
console.log(this.changeComponent.names);
}
}
CodePudding user response:
There are a lot of ways for components to communicate with each other. In that example I would create a service that will be used to hold and manipulate the state.
Here's a link: https://stackblitz.com/edit/angular-ivy-fzd5rx
CodePudding user response:
I suggest to form your question to be: how to update an input value in a component from a sibling component?
Answer
A component itself can not directly change an @Input value in other siblings components.
Here are some ways to do this:
My suggested way
Implement the ControlValueAccessor on your change component to enable the ngModel two way binding on it. And then pass your variable (names) in the two way binding ngModel of your change component, which will take care of changing that value on action and emits the changed value back up to the parent component. That is all you need. Next time the change detection is triggered, the change will apply and your preview component will get the new value through the @Input.
Example:
In your change component:
import { Component, forwardRef} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-change',
templateUrl: './change.component.html',
styleUrls: ['./change.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ChangeComponent),
multi: true,
},
],
})
export class ChangeComponent implements ControlValueAccessor {
names;
onChange;
onTouched;
writeValue(obj: any): void {
this.names = obj;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
changeName() {
this.names.pop('Test2');
this.onChange(this.names.slice());
console.log(this.names);
}
}
In your parent component template:
<button (click)="onEnter()">Set Name</button>
<app-table [names]="names"> </app-table>
<app-change [(ngModel)]="names"> </app-change>
This example is very similar to the @Input @Output way to communicate between components, where you change an @Input value between siblings by emitting the new value from the change component up to the parent and the parent will automatically pass the new value the preview component when the angular change detection is triggered.
Here is my stackblitz example
Another way to do this
Provide a service on top of all the siblings and define your value to change in your service and the inject your service in the change sibling and the preview sibling components and change the value directly in the service, this way does not require the the angular @Input decorator.
At the end checkout angular documentation about the components interaction for better understanding.