SoFunction
Updated on 2025-04-08

Detailed explanation of Angular2 component interaction example

1. Component communication

We know that Angular2 applications actually have many component trees composed of parent-child valences. Therefore, understanding how components communicate, especially between parent-child components, is of great significance to writing Angular2 applications. Generally speaking, there are mainly the following ways of interaction between components:

l Use input binding to pass data from parent component to child component

l Intercept the change of input attribute value through setter

l Use ngOnChanges to intercept changes in input attribute values

l Parent component listens for events in child components

l Parent component and child component interact through local variables

l Parent component calls ViewChild

l Parent and child components communicate through services

This article will give a general introduction to the communication between components by explaining several methods.

2. Input type binding

Input binding refers to the use of attribute binding method in template syntax to pass the data of the parent component to the object corresponding to the child component. The objects in the child component are generally modified using the @Input decorator as the recipient of the data, for example.

@Component({
selector: 'child',
template: 'I am fron {{input}}'
})
export class ChildComponent implements OnInit {
@Input()
input;
constructor() { }
ngOnInit() { }
}
@Component({
selector: 'parent',
template: '<child [input]="data"></child>'
})
export class ParentComponent implements OnInit {
data: string;
constructor() { }
ngOnInit() {
 = "parent";
}
}

In the above example, we can see that there are two components of parent and child. The <child [input]="data"></child> child component is introduced into the template in the parent component ParentComponent, and the data data is bound to the input attribute through the property binding method and passed into the child component. The subcomponent modifies the input attribute through the @Input() annotation to receive the incoming data and display it in the template I am fron {{input}}.

Input binding is the most common way to pass data from a parent component to a child component.

3. Setter monitoring

We know that Angular2 is a MVVM framework that can be displayed synchronously into the template view when data changes. You can use a setter function of input properties to intercept changes in the value in the parent component and take action. For example, we transform the above example, using set and get in the subcomponent to rewrite the corresponding bound input attribute, and output a console information when the input value changes.

@Component({
selector: 'child',
template: 'I am fron {{data}}'
})
export class ChildComponent implements OnInit {
_input:string;
@Input()
public set input(v : string) {
this._input = v;
(v);
}
public get input() : string {
return this._input;
}
constructor() { }
ngOnInit() { }
}

4. ngOnChanges

In addition to the setter function mentioned above, it can respond to changes in input data, Angular2 also provides a lifecycle function ngOnChanges to listen to changes in data. Use the ngOnChanges method of the OnChanges lifecycle hook interface to monitor changes in input attribute values ​​and respond. We transform the above subcomponents to respond to the corresponding changes. In this example, we listened to the changes in the input data, and the corresponding actions we took were just to output the corresponding information. Of course, you can do many other things.

@Component({
selector: 'child',
template: 'I am fron {{data}}'
})
export class ChildComponent implements OnInit, OnChanges {
_input: string;
@Input()
public set input(v: string) {
this._input = v;
(v);
}
public get input(): string {
return this._input;
}
constructor() { }
ngOnInit() { }
ngOnChanges(changes: SimpleChanges) {
(changes);
}
}

5. Event spread

The above centralized methods are how the parent component passes data to the child component and how the child component listens to data changes. Event propagation is a way for how the child component communicates to the parent component. The child component exposes an EventEmitter property, which is used by the child component when an event occurs, the emits event is emitted. The parent component is bound to this event property and responds to the event when it occurs. The EventEmitter property of a child component is an output property, usually with the @Output decorator.

@Component({
selector: 'child',
template: `
I am fron {{data}}<br />
<button  (click)="click()">click for out</button>
`
})
export class ChildComponent implements OnInit, OnChanges {
_input: string;
@Input()
public set input(v: string) {
this._input = v;
(v);
}
public get input(): string {
return this._input;
}
@Output()
output:EventEmitter<string> = new EventEmitter<string>();
click(){
("i am from child");
}
constructor() { }
ngOnInit() { }
ngOnChanges(changes: SimpleChanges) {
(changes);
}
}
@Component({
selector: 'parent',
template: '<child [input]="data" (output)="output($event)"></child>'
})
export class ParentComponent implements OnInit {
data: string;
constructor() { }
ngOnInit() {
 = "parent";
}
output($event){
($event);
}
}

In the example above, we are in the child componentChildComponentAdded an outward propagation eventoutput:EventEmitter<string> = new EventEmitter<string>() and added a clicked button. When the button event is triggered, the output event is called to pass the event to the parent component and the data is passed as a parameter to the parent component.ParentComponentin the parent componentParentComponentTemplate<child [input]="data" (output)="output($event)"></child>It can be seen in this article that we use event binding in template syntax to bind the output function as the acceptance function of the corresponding event. When the child component output event is triggered, the function of the parent component will be executed.

Using event propagation to communicate between child components to parent components is the most common way.

6. Local variables

In template syntax, we know that there is a syntax such as local variables, and local variables can be used to represent the corresponding components. Although the parent component cannot use data binding to read the properties of a child component or call the child component's methods. However, you can create a new local variable in the parent component template to represent the child component, and then use this variable to read the properties of the child component and call the child component method. However, this usage method can only be used in the template. For example, as shown below, rewrite the parent component template in the above example, and the code is as follows.

We're inParentComponentThe local variable #child is used in the component to obtain an instance of the child component, so that its properties or methods can be used in the template, for example.

@Component({
selector: 'parent',
template: '<child [input]="data" (output)="output($event)" #child></child>{{}}'
})
export class ParentComponent implements OnInit {
data: string;
constructor() { }
ngOnInit() {
 = "parent";
}
output($event){
($event);
}
}

7. ViewChild

The way to local variables is to get instances of child components in the template of the parent component. Is there any other way to get instances of child components in the component's class? The answer is yes. If the parent component's class needs to read the attribute value of the child component or call the child component's method, the local variable method cannot be used. When the parent component class requires this access, the child component can be injected into the parent component as ViewChild. For example, we transform the component class of the parent component above and use ViewChild to get an instance of the child component. The code is as follows:

@Component({
selector: 'parent',
template: '<child [input]="data" (output)="output($event)" #child></child>{{}}'
})
export class ParentComponent implements OnInit {
@ViewChild(ChildComponent)
private childComponent: ChildComponent;
data: string;
constructor() { }
ngOnInit() {
 = "parent";
}
output($event) {
($event);
}
}

In the above code, we use@ViewChild(ChildComponent)The annotation obtains an instance of the corresponding child component childComponent, so that the corresponding properties and methods of the child component can be called in the parent component class.

Compared with the local variable method, ViewChild method is more flexible and has a wide range of uses. However, one thing to note is that you must wait for the parent component's view to be displayed before it can be used, so the ngAfterViewInit lifecycle hook is a very important step.

8. Service method

Through service dependency injection, we can understand that services can be shared between parent and child components, so we can use the shared service to communicate between parent and child components.

If we limit the scope of the service instance to the parent and its child components, components outside of this component subtree will not be able to access the service or communicate with them.

Generally speaking, the use of services between father and son is implemented in the form of event messages.

For example, in the following code, the service service is shared in the parent and child component, and an instance of the service service is obtained in their respective classes. When the buttons in the parent and child component are clicked separately, the corresponding input$ and output$ in the Service service can be triggered. Because the service is shared, listening to the corresponding service information in the parent and child component can obtain the delivered message.

@Injectable()
export class Service {
input$: EventEmitter<string> = new EventEmitter<string>();
output$: EventEmitter<string> = new EventEmitter<string>();
constructor() {
}
}
@Component({
selector: 'child',
template: `
<button  (click)="click()">click for output</button>
`
})
export class ChildComponent {
constructor(private _service: Service) {
this._service.input$.subscribe(function (input: string) {
(input);
})
}
click() {
this._service.output$.emit('i am from child');
}
}
@Component({
selector: 'parent',
template: '<child></child><button  (click)="click()">click for input</button>',
providers: [Service]
})
export class ParentComponent {
constructor(private _service: Service) {
this._service.output$.subscribe(function (output: string) {
(output);
})
}
click() {
this._service.input$.emit('i am from child');
}
}

Summarize

The above is a detailed explanation of the Angular2 component interaction example introduced by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support for my website!