Angular 2 嵌套组件数据传递

在开始本文之前,建议先阅读之前的两篇文章以获得更好的理解。本文提到的源代码可以在之前的文章中找到。本文将介绍如何在Angular 2框架中创建一个嵌套组件,并从父组件向子组件传递数据。

先决条件:

  • 已设置Angular 2开发环境(参考:)
  • 基本运行的Angular 2应用(参考:)

开始之前

首先,复制之前文章的源代码()到一个新的文件夹中,命名为nestedComponent。然后在nestedComponent文件夹中重新安装npm包,使用命令npm install。安装完成后,文件夹结构应该如下所示:

创建嵌套组件

将从student-form组件中移除标签,这是更新后的student-form.html的样子:

<div> Student First Name :-<br/> <input [(ngModel)]="Student.FirstName" type="text"><br/> Student Last Name :-<br/> <input [(ngModel)]="Student.LastName" type="text"><br/> Student Age :-<br/> <input [(ngModel)]="Student.Age" type="text"><br/> </div>

接下来,在app文件夹中添加一个新的文件,命名为student-detail.component.ts。这个文件将包含student-detail组件的逻辑:

import { Component, Input } from '@angular/core'; @Component({ selector: 'student-detail', templateUrl: '../view/student-detail.html' }) export class StudentDetailComponent { @Input() FirstName: String; @Input() LastName: String; @Input() Age: number; }

在这个组件中,将从父组件传递数据以便渲染。为此,还需要导入Input。在第4行和第5行定义了selectortemplateUrl。为了将父组件的输入映射到Student-Detail组件,在第9行、第10行和第11行定义了@Input()并定义了FirstNameLastNameAge

还可以为变量和属性名设置不同的名称。要设置不同的属性名,需要在括号内定义名称,例如:@Input('first-name')

import { Component, Input } from '@angular/core'; @Component({ selector: 'student-detail', templateUrl: '../view/student-detail.html' }) export class StudentDetailComponent { @Input('first-name') FirstName: String; @Input('last-name') LastName: String; @Input() Age: number; }

类似地,也可以从父组件使用Output来传递方法。为此,需要注入OutputEventEmitter依赖,然后添加一个方法来调用父组件的方法。

import { Component, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'student-detail', templateUrl: '../view/student-detail.html' }) export class StudentDetailComponent { @Input('first-name') FirstName: String; @Input('last-name') LastName: String; @Input() Age: number; @Output('onButtonClick') buttonClick = new EventEmitter(); onCLick() { this.buttonClick.emit(); } }

现在需要添加在第5行引用的HTML文件。将此文件添加到view文件夹中,并将其命名为student-detail.html

<section> <br/> <div> Student Details are ... </div> <div> First Name : {{FirstName}} <br/> Last Name : {{LastName}} <br/> Age : {{Age}} </div> <button (click)="onCLick()"> Click Me </button> <br/> <ng-content></ng-content> </section>

在刚刚添加的HTML模板中,引用了student-detail.component.ts中定义的变量(第5、6和7行)。在上面的HTML模板中突出显示了这个变量名称。在第7行,映射了onClick方法,它将内部调用父组件映射到它的方法。

在HTML模板中,还添加了ng-content标签。这个标签将渲染放置在student-detail标签之间的内容。当在主组件student-form中添加student-detail标签时,将更多地讨论这一点。让开始在student-form中注入新创建的组件。这是带有student-detail标签的更新模板:

<div> Student First Name :-<br/> <input [(ngModel)]="Student.FirstName" type="text"><br/> Student Last Name :-<br/> <input [(ngModel)]="Student.LastName" type="text"><br/> Student Age :-<br/> <input [(ngModel)]="Student.Age" type="text"><br/> <student-detail first-name="{{Student.FirstName}}" last-name="{{Student.LastName}}" [Age]="{{Student.Age}}" (onButtonClick)="onButtonClick()"> <div> This is inside nested control </div> </student-detail> </div>

在第5行和第6行,添加了student-detail标签属性FirstNameLastNameAge,并映射了相应的父变量。onButtonClick()方法映射到子控件。使用了花括号来映射变量,但也可以像下面提到的那样使用方括号:

<student-detail [first-name]="Student.FirstName" [last-name]="Student.LastName" [Age]="Student.Age" (onButtonClick)="onButtonClick()"> <div> This is inside nested control </div> </student-detail>

现在需要在student.component.ts中添加onButtonClick方法。

import { Component } from '@angular/core'; import { StudentModel } from './student.model'; @Component({ selector: 'student-form', templateUrl: '../view/student-form.html' }) export class StudentComponent { Student: StudentModel = new StudentModel(); onButtonClick = function() { alert('Hey, button was clicked in child control'); } }

如果注意到student-detail标签之间的div标签,它将被传递到student-detail组件中,并将在添加到student-detail组件中的ng-content标签内渲染。如果使用过Angular 1.x,这类似于ng-transclude

最后一步是在student.module.ts中映射依赖。以下是更新后的student.module.ts,已经突出显示了对文件所做的更改。

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { StudentComponent } from './student.component'; import { StudentDetailComponent } from './student-detail.component'; import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ StudentComponent, StudentDetailComponent ], bootstrap: [ StudentComponent ] }) export class AppModule { }

在第4行,导入了studentDetailComponent,在第9行,将同一个对象映射到声明中。这是最终的文件夹结构:

现在打开命令提示符,导航到基础文件夹并执行npm start。现在应该可以在默认浏览器中看到最终输出。如果在文本框中输入,相同的内容应该在嵌套组件中显示。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485