热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Angular组件交互步骤详解

这次给大家带来Angular组件交互步骤详解,Angular组件交互步骤详解的注意事项有哪些,下面就是实战案例,一起来看一下。在Angular应用开发


这次给大家带来Angular组件交互步骤详解,Angular组件交互步骤详解的注意事项有哪些,下面就是实战案例,一起来看一下。

在Angular应用开发中,组件可以说是随处可见的。本篇文章将介绍几种常见的组件通讯场景,也就是让两个或多个组件之间交互的方法。

根据数据的传递方向,分为父组件向子组件传递、子组件向父组件传递及通过服务传递三种交互方法。

父组件向子组件传递

子组件通过@Input装饰器定义输入属性,然后父组件在引用子组件的时候通过这些输入属性向子组件传递数据,子组件可通过setter或ngOnChanges()来截听输入属性值的变化。

先定义两个组件,分别为子组件DemoChildComponent和父组件DemoParentComponent.

子组件:

@Component({
selector: 'demo-child',
template: `

{{paramOne}}


{{paramTwo}}


})
export class DemoChildComponent {
@Input() paramOne: any; // 输入属性1
@Input() paramTwo: any; // 输入属性2
}

子组件通过@Input()定义输入属性paramOne和paramTwo(属性值可以为任意数据类型)

父组件:

@Component({
selector: 'demo-parent',
template: `

`
})
export class DemoParentComponent {
paramOneVal: any = '传递给paramOne的数据';
paramTwoVal: any = '传递给paramTwo的数据';
}

父组件在其模板中通过选择器demo-child引用子组件DemoChildComponent,并通过子组件的两个输入属性paramOne和paramTwo向子组件传递数据,最后在子组件的模板中就显示传递给paramOne的数据和传递给paramTwo的数据这两行文本。

通过 setter 截听输入属性值的变化

在实际应用中,我们往往需要在某个输入属性值发生变化的时候做相应的操作,那么此时我们需要用到输入属性的 setter 来截听输入属性值的变化。

我们将子组件DemoChildComponent进行如下改造:

@Component({
selector: 'demo-child',
template: `

{{paramOneVal}}


{{paramTwo}}


`
})
export class DemoChildComponent {
private paramOneVal: any;
@Input()
set paramOne (val: any) { // 输入属性1
this.paramOneVal= val;
// dosomething
};
get paramOne () {
return this.paramOneVal;
};
@Input() paramTwo: any; // 输入属性2
}

在上面的代码中,我们可以看到通过paramOne属性的 setter 将拦截到的值val赋值给内部私有属性paramOneVal,达到父组件传递数据给子组件的效果。当然,最重要的是,在 setter 里面你可以做更多的其它操作,程序的灵活性就更强了。

通过ngOnChanges()来截听输入属性值的变化

通过 setter 截听输入属性值的变化的方法只能对单个属性值变化进行监视,如果需要监视多个、交互式输入属性的时候,这种方法就显得力不从心了。而通过使用 OnChanges 生命周期钩子接口的 ngOnChanges() 方法(当组件通过@Input装饰器显式指定的那些变量的值变化时调用)就可以实现同时监视多个输入属性值的变化。

在子组件DemoChildComponent新增ngOnChanges:

@Component({
selector: 'demo-child',
template: `

{{paramOneVal}}


{{paramTwo}}


`
})
export class DemoChildComponent implements OnChanges {
private paramOneVal: any;
@Input()
set paramOne (val: any) { // 输入属性1
this.paramOneVal= val;
// dosomething
};
get paramOne () {
return this.paramOneVal;
};
@Input() paramTwo: any; // 输入属性2
ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
for (let propName in changes) { // 遍历changes
let changedProp = changes[propName]; // propName是输入属性的变量名称
let to = JSON.stringify(changedProp.currentValue); // 获取输入属性当前值
if (changedProp.isFirstChange()) { // 判断输入属性是否首次变化
console.log(`Initial value of ${propName} set to ${to}`);
} else {
let from = JSON.stringify(changedProp.previousValue); // 获取输入属性先前值
console.log(`${propName} changed from ${from} to ${to}`);
}
}
}
}

新增的ngOnChanges方法接收的参数changes是以输入属性名称为键、值为SimpleChange的对象,SimpleChange对象含有当前输入属性是否第一次变化、先前值、当前值等属性。因此在ngOnChanges方法中通过遍历changes对象可监视多个输入属性值并进行相应的操作。

获取父组件实例

前面介绍的都是子组件通过@Input装饰器定义输入属性,这样父组件可通过输入属性将数据传递给子组件。

当然,我们可以想到一种更主动的方法,那就是获取到父组件实例,然后调用父组件的某个属性或方法来获取需要的数据。考虑到每个组件的实例都会添加到注入器的容器里,因此可通过依赖注入来找到父组件的示例。

子组件获取父组件实例相比于父组件获取子组件实例(直接通过模板变量、@ViewChild或@ViewChildren获取)要麻烦一些。

要在子组件中获取父组件的实例,有两种情况:

已知父组件的类型

这种情况可以直接通过在构造函数中注入DemoParentComponent来获取已知类型的父组件引用,代码示例如下:

@Component({
selector: 'demo-child',
template: `

{{paramOne}}


{{paramTwo}}


`
})
export class DemoChildComponent {
paramOne: any;
paramTwo: any;
constructor(public demoParent: DemoParentComponent) {
// 通过父组件实例demoParent获取数据
this.paramOne= demoParent.paramOneVal;
this.paramTwo = demoParent.paramTwoVal;
}
}

未知父组件的类型

一个组件可能是多个组件的子组件,有时候无法直接知道父组件的类型,在Angular中,可通过类—接口(Class-Interface)的方式来查找,即让父组件通过提供一个与类—接口标识同名的别名来协助查找。

首先创建DemoParent抽象类,它只声明了paramOneVal和paramTwoVal属性,没有实现(赋值),示例代码如下:

export abstract class DemoParent {
paramOneVal: any;
paramTwoVal: any;
}

然后在父组件DemoParentComponent的providers元数据中定义一个别名 Provider,用 useExisting 来注入父组件DemoParentComponent的实例,代码示例如下:

@Component({
selector: 'demo-parent',
template: `

`,
providers: [{provider: DemoParent, useExisting: DemoParentComponent}]
})
export class DemoParentComponent implements DemoParent {
paramOneVal: any = '传递给paramOne的数据';
paramTwoVal: any = '传递给paramTwo的数据';
}

然后在子组件中就可通过DemoParent这个标识找到父组件的示例了,示例代码如下:

@Component({
selector: 'demo-child',
template: `

{{paramOne}}


{{paramTwo}}


`
})
export class DemoChildComponent {
paramOne: any;
paramTwo: any;
constructor(public demoParent: DemoParent) {
// 通过父组件实例demoParent获取数据
this.paramOne= demoParent.paramOneVal;
this.paramTwo = demoParent.paramTwoVal;
}
}

子组件向父组件传递

依然先定义两个组件,分别为子组件DemoChildComponent和父组件DemoParentComponent.

子组件:

@Component({
selector: 'demo-child',
template: `

子组件DemoChildComponent


`
})
export class DemoChildComponent implements OnInit {
readyInfo: string = '子组件DemoChildComponent初始化完成!';
@Output() ready: EventEmitter = new EventEmitter(); // 输出属性
ngOnInit() {
this.ready.emit(this.readyInfo);
}
}

父组件:

@Component({
selector: 'demo-parent',
template: `



readyInfo: {{demoChild.readyInfo}}




readyInfo: {{demoChildComponent.readyInfo}}


`
})
export class DemoParentComponent implements AfterViewInit {
// @ViewChild('demoChild') demoChildComponent: DemoChildComponent; // 通过模板别名获取
@ViewChild(DemoChildComponent) demoChildComponent: DemoChildComponent; // 通过组件类型获取
ngAfterViewInit() {
console.log(this.demoChildComponent.readyInfo); // 打印结果:子组件DemoChildComponent初始化完成!
}
onReady(evt: any) {
console.log(evt); // 打印结果:子组件DemoChildComponent初始化完成!
}
}

父组件监听子组件的事件

子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。

在上面定义好的子组件和父组件,我们可以看到:

子组件通过@Output()定义输出属性ready,然后在ngOnInit中利用ready属性的 emits(向上弹射)事件。

父组件在其模板中通过选择器demo-child引用子组件DemoChildComponent,并绑定了一个事件处理器(onReady()),用来响应子组件的事件($event)并打印出数据(onReady($event)中的$event是固定写法,框架(Angular)把事件参数(用 $event 表示)传给事件处理方法)。

父组件与子组件通过本地变量(模板变量)互动

父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法。

在上面定义好的子组件和父组件,我们可以看到:

父组件在模板demo-child标签上定义了一个demoChild本地变量,然后在模板中获取子组件的属性:



readyInfo: {{demoChild.readyInfo}}

父组件调用@ViewChild()

本地变量方法是个简单便利的方法。但是它也有局限性,因为父组件-子组件的连接必须全部在父组件的模板中进行。父组件本身的代码对子组件没有访问权。

如果父组件的类需要读取子组件的属性值或调用子组件的方法,就不能使用本地变量方法。

当父组件类需要这种访问时,可以把子组件作为 ViewChild,注入到父组件里面。

在上面定义好的子组件和父组件,我们可以看到:

父组件在组件类中通过@ViewChild()获取到子组件的实例,然后就可以在模板或者组件类中通过该实例获取子组件的属性:



readyInfo: {{demoChildComponent.readyInfo}}

ngAfterViewInit() {
console.log(this.demoChildComponent.readyInfo); // 打印结果:子组件DemoChildComponent初始化完成!
}

通过服务传递

Angular的服务可以在模块注入或者组件注入(均通过providers注入)。

在模块中注入的服务在整个Angular应用都可以访问(除惰性加载的模块)。

在组件中注入的服务就只能该组件和其子组件进行访问,这个组件子树之外的组件将无法访问该服务或者与它们通讯。

下面的示例就以在组件中注入的服务来进行父子组件之间的数据传递:

通讯的服务:

@Injectable()
export class CallService {
info: string = '我是CallService的info';
}

父组件:

@Component({
selector: 'demo-parent',
template: `




{{callService.info}}


`,
providers: [CallService]
})
export class DemoParentComponent {
constructor(public callService: CallService) {
console.log(callService.info); // 打印结果:我是CallService的info
}
changeInfo() {
this.callService.info = '我是被父组件改变的CallService的info';
}
}

子组件:

@Component({
selector: 'demo-child',
template: `

`
})
export class DemoChildComponent {
constructor(public callService: CallService) {
console.log(callService.info); // 打印结果:我是CallService的info
}
changeInfo() {
this.callService.info = '我是被子组件改变的CallService的info';
}
}

上面的代码中,我们定义了一个CallService服务,在其内定义了info属性,后面将分别在父子组件通过修改这个属性的值达到父子组件互相传递数据的目的。

然后通过DemoParentComponent的providers元数据数组提供CallService服务的实例,并通过构造函数分别注入到父子组件中。

此时,通过父组件改变info按钮或子组件改变info按钮在父组件或子组件中改变CallService服务的info属性值,然后在页面可看到改变之后对应的info属性值。

相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!

推荐阅读:

Node module模块使用详解(附代码)

jQuery+COOKIE实现切换皮肤效果实现(附代码)

以上就是Angular组件交互步骤详解的详细内容,更多请关注其它相关文章!



推荐阅读
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • PHP反射API的功能和用途详解
    本文详细介绍了PHP反射API的功能和用途,包括动态获取信息和调用对象方法的功能,以及自动加载插件、生成文档、扩充PHP语言等用途。通过反射API,可以获取类的元数据,创建类的实例,调用方法,传递参数,动态调用类的静态方法等。PHP反射API是一种内建的OOP技术扩展,通过使用Reflection、ReflectionClass和ReflectionMethod等类,可以帮助我们分析其他类、接口、方法、属性和扩展。 ... [详细]
  • Python基础知识:注释、输出和input交互
    本文介绍了Python基础知识,包括注释的使用、输出函数print的用法以及input函数的交互功能。其中涉及到字符串和整数的类型转换等内容。 ... [详细]
author-avatar
老做梦不醒_780
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有