65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Angular 2 中构建嵌套组件

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.67/5 (5投票s)

2016 年 12 月 29 日

CPOL

3分钟阅读

viewsIcon

21884

downloadIcon

275

使用 Angular 2 构建嵌套组件,并在父子组件之间传递数据

引言

在本文中,我们将研究如何使用 Angular 2 框架创建嵌套组件,并将数据从父组件传递到子组件。在阅读本文之前,我建议您阅读我之前的两篇文章以获得更好的理解。本文引用了之前文章中提供的源代码,请点击此处

我想收到对本文的反馈。请随时在下面分享您的评论。如果您喜欢这篇文章,请不要忘记评价它。

必备组件

  • Angular 2 开发环境已设置好 (参考请点击此处)
  • 基本运行的 Angular 2 应用程序 (参考请点击此处)

开始吧

让我们开始吧,将上一篇文章的源代码(可在此处获取)复制到新文件夹nestedComponent。在 nestedComponent 文件夹中,我们需要使用 npm install 重新安装 npm 包。这是在 npm install 之后您的文件夹应显示的样子。

在本文中,我们将把原本在 student-form 组件底部渲染的标签移动到嵌套组件中。这是删除标签后我们的 student-form.html 的样子。

<div>
    Student First Name :- <input [(ngModel)] = "Student.FirstName" type="text"><br/>
    Student Last Name :- <input [(ngModel)] = "Student.LastName" type="text"><br/>
    Student Age :- <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;
}

在这个组件中,我们将从父控件传递数据以进行渲染。为了实现这一点,我们还将从 angular/core 导入 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 依赖项,然后添加一个方法来触发 parent 方法。

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 模板中,我们引用了在第 5、6 和 7 行的 student-detail.component.ts 中定义的变量。我已经在上面的 HTML 模板中高亮显示了这些变量名。在第 7 行,我们映射了 onClick 方法,该方法将在内部触发映射到它的 parent 控件方法。

在 HTML 模板中,我们还添加了 ng-content 标签。此标签将渲染我们放置在 student-detail 标签之间的内容。当我们向我们的主组件 student-form 添加 student-detail 标签时,我们将对此进行更多讨论。让我们开始在 student-form 中注入我们新创建的组件。这是更新后的带有 student-detail 标签的模板。

<div>
     Student First Name :- <input [(ngModel)]="Student.FirstName" type="text"><br/>
     Student Last Name :- <input [(ngModel)]="Student.LastName"  type="text"><br/>
     Student Age :- <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 标签属性,FirstName LastNameAge,并具有相应的父变量映射。 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>

现在我们需要将 onButtonClick 方法添加到 student.component.ts

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。现在您应该在默认浏览器中看到最终输出。如果您在文本框中输入内容,则应将其显示在嵌套组件内。

摘要

在本文中,我们创建了一个嵌套组件,该组件从父组件获取数据然后渲染它。我们还研究了几种可以将数据与子控件映射的方式。

参考

© . All rights reserved.