Topic 6: Two-Way Data Binding and child-parent component communication

Github project link – https://github.com/kuldeep101990/angular-step6

In this step, we’ll explore two-way data binding and parent-child communication in Angular, comparing these concepts to familiar patterns in Java. Two-way data binding allows seamless interaction between the component and template, much like managing form inputs and bean properties in Java-based applications.


Step 1: Two-Way Data Binding Using ngModel

Overview
Two-way data binding ensures that changes in the component logic are reflected in the template and vice versa. This is comparable to how a JavaBean’s properties sync with form inputs in Java web applications using getter and setter methods.


Implementing Two-Way Data Binding

Update the Template
Add the following code to the home.component.html file:

<div class="play-container">
    <p>
        <input type="text" [(ngModel)]="name"><br>
        <strong>You said: </strong> {{ name }}
    </p>
</div>

Explanation:

  1. [(ngModel)]="name": The [(ngModel)] syntax binds the value of the input field to the name property in the component.
  2. {{ name }}: Displays the value of the name property dynamically.

Java Comparison:

In a JSP:

<form>
    <input type="text" name="name" value="${user.name}" />
    <p>You said: ${user.name}</p>
</form>

Here, ${user.name} displays the value of the name property from a JavaBean.


Import FormsModule

To use ngModel, import FormsModule in your app.module.ts:

// other imports
import { FormsModule } from '@angular/forms';
@NgModule({
  ...
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule  // Add this import
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Java Comparison:

In Spring MVC, you would add dependencies for handling forms in your project configuration, like including Spring Web and Thymeleaf dependencies in your pom.xml file.


Define the Property in the Component

Update the home.component.ts file to include the name property:

export class HomeComponent implements OnInit {
  name: string = '';  // Initialize the property
  constructor() { }
  ngOnInit() {}
}

Java Comparison:

In Java, you might define a bean with a property and getter/setter methods to handle form data:

public class User {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

In a JSP, you would access the name property with JSP EL: ${user.name}.


Step 2: Parent-Child Communication with @Input and @Output

Parent-child communication in Angular allows components to share data and interact, similar to the relationship between servlets and JSPs in Java or controller-service layers.

Using @Input

The @Input decorator lets a parent component pass data to a child component.

Example:

Parent template (app.component.html):

<app-child [parentData]="messageFromParent"></app-child>

Child component (child.component.ts):

import { Component, Input } from '@angular/core';
@Component({
  selector: 'app-child',
  template: '<p>{{ parentData }}</p>',
})
export class ChildComponent {
  @Input() parentData: string = '';  // Receives data from parent
}

Java Comparison:

In Java, passing data between layers (controller → service → JSP) is common. For example:

@Controller
public class ParentController {
    @GetMapping("/")
    public String sendData(Model model) {
        model.addAttribute("message", "Hello from Parent!");
        return "child";
    }
}

In the JSP:

<p>${message}</p>


Using @Output

The @Output decorator allows the child component to emit events that the parent component can listen to.

Example:

Child component (child.component.ts):

import { Component, Output, EventEmitter } from '@angular/core';
@Component({
  selector: 'app-child',
  template: '<button (click)="sendData()">Send Data</button>',
})
export class ChildComponent {
  @Output() dataEvent = new EventEmitter<string>();
  sendData() {
    this.dataEvent.emit('Hello from Child!');
  }
}

Parent template (app.component.html):

<app-child (dataEvent)="receiveData($event)"></app-child>
<p>{{ messageFromChild }}</p>

Parent component (app.component.ts):

export class AppComponent {
  messageFromChild: string = '';
  receiveData(event: string) {
    this.messageFromChild = event;
  }
}

Java Comparison:

This is similar to a servlet forwarding data to another servlet or JSP:

// In ChildServlet
request.setAttribute("childMessage", "Hello from Child!");
request.getRequestDispatcher("parent.jsp").forward(request, response);

In the JSP:

<p>${childMessage}</p>


Major Version Differences

  1. Angular 5:
    • Required explicit imports for FormsModule to enable two-way data binding with ngModel.
    • Java Comparison: Comparable to adding form-handling dependencies to your Java web application manually.
  2. Angular 11+:
    • Improved diagnostics for binding issues, making debugging templates easier.
    • Java Comparison: Similar to stricter compilation checks introduced in modern Java versions (e.g., with generics or lambda expressions).

Conclusion

Two-way data binding (ngModel) in Angular is similar to using JavaBeans for form handling and JSP for rendering data. Additionally, @Input and @Output decorators enable parent-child communication, resembling the way servlets or controllers interact with views in Java.

By leveraging Angular’s advanced binding techniques, you can build dynamic, interactive web applications while drawing parallels to familiar Java concepts.


Leave a Reply

Your email address will not be published. Required fields are marked *