angular 输入输出_Angular 2组件:输入和输出

angular 输入输出

在本文中,我们将进一步介绍Angular 2组件-如何定义它们,以及如何将数据放入其中以及从中取出。

这是Angular 2系列的第二部分。 您可以在这里阅读第一部分。 我们在之前的文章中介绍了组件和装饰器的基本概念,并特别看到了用于构建Angular应用程序的@Component@View装饰器。 本文将深入探讨。 但是,我们无法在一篇文章中涵盖有关组件的所有内容,因此以后的文章将介绍Angular 2组件的其他方面。

这篇文章和该系列其他文章的代码可在angular2-samples回购中获得。 您还可以在以下网址查看运行的示例: http : //angular2-samples.azurewebsites.net/

尽管可以在ECMAScript 5(浏览器支持的最常见JavaScript版本)中编写Angular 2应用程序,但我们更喜欢使用TypeScript编写。 Angular 2本身是用TypeScript编写的,它在开发时为我们提供了帮助,并包括使我们更容易定义Angular 2组件的功能。

特别是,TypeScript支持装饰器(有时称为“注释”),这些装饰器用于声明性地添加或更改现有的“事物”。 例如,类装饰器可以将元数据添加到类的构造函数中,甚至可以更改类的行为。 有关装饰器以及您可以使用它们进行的操作的类型的更多信息,请参阅JavaScript装饰器的建议。 Angular 2包含多个装饰器。

正如我们在之前的文章中所介绍的那样,Angular 2组件是Angular应用程序的关键构建块。 它们包括一个用HTML和CSS定义的视图,以及一个实现该视图所需功能的关联控制器。 控制器具有三项主要职责:

  • 管理模型,即视图使用的应用程序数据
  • 实现视图所需的方法,例如提交数据或隐藏/显示UI的部分
  • 管理与视图状态相关的数据,例如当前选择列表中的哪个项目。

根据您的背景,上面的列表可能听起来很熟悉。 实际上,Angular组件控制器听起来很像John Gossman在2005年定义的视图模型的原始定义:

该术语的意思是“视图的模型”,可以被认为是视图的抽象,但是它也提供了视图可以用于数据绑定的模型的特殊化。 在后一个角色中,ViewModel包含将模型类型转换为视图类型的数据转换器,并且包含视图可用于与模型进行交互的命令。 — 来源 (捕获于2015年11月27日)

由于Angular 2组件不是本机JavaScript实体,因此Angular提供了一种通过将构造函数与视图配对来定义组件的方法。 您可以通过定义构造函数(在TypeScript中将其定义为类)并使用装饰器将视图与构造函数相关联来实现此目的。 装饰器还可以为组件设置各种配置参数。 使用我们在本系列的第一篇文章中看到的@Component装饰器,可以实现这种魔力。

组件层次结构

上面描述了一个单独的组件,但是Angular 2应用程序实际上是由组件层次结构组成的-它们以根组件开头,该根组件包含该应用程序中使用的所有组件作为后代。 Angular 2组件旨在成为独立的,因为我们希望封装我们的组件函数,并且我们不希望其他代码任意进入我们的组件以读取或更改属性。 另外,我们不希望我们的组件影响其他人编写的另一个组件。 一个明显的例子是CSS:如果我们为一个组件设置CSS,我们不希望我们CSS“渗出”到另一个组件,就像我们不希望其他CSS“渗入”到我们的组件一样。

同时,组件确实需要交换数据。 Angular 2组件可以从其父级接收数据,只要接收组件明确表示愿意接收数据即可。 同样,组件可以通过触发父级侦听的事件将数据发送到其父级。 让我们看一下组件层次结构的行为。 首先,我们可以如下绘制它:

Angular 2组件:组件层次结构行为

每个盒子都是一个组件,从技术上讲,这种表示形式称为“图形” —由节点和连接的“边”组成的数据结构。 箭头表示从一个组件到另一组件的数据流,我们可以看到数据仅在一个方向上-从顶部向下到后代。 另外,请注意,没有任何路径可让您从一个节点穿过其他节点再回到起点。 这种数据结构的正式名称是“有向无环图”,也就是说,它仅在一个方向上流动,并且没有循环路径。

这种结构具有一些重要的特征:它是可预测的,它很容易遍历,并且很容易看到更改后的影响。 出于Angular的目的,当一个节点中的数据发生更改时,很容易找到可能受影响的下游节点。

一个简单的示例可能是一个表,其中的行包含客户及其相关信息,其中表组件包含代表每个客户的多个单独的行组件。 表组件可以管理包含所有客户的记录集,并将单个客户的数据传递到它包含的每个行组件。

这对于仅显示数据来说效果很好,但是在现实世界中,数据将需要以另一种方式流动-备份层次结构-例如在用户编辑行时。 在这种情况下,该行需要告知表组件该行的数据已更改,因此可以将更改发送回服务器。 问题是,如上图所示,数据仅沿层次结构向下流动,而没有备份。 为了确保我们保持层次结构中单向数据流的简单性,Angular 2使用不同的机制将数据发送回层次结构:事件。

Angular 2组件:层次结构中的单向数据流

现在,当子组件执行父项需要了解的操作时,子项将触发父项捕获的事件。 父级可以采取任何所需的措施,其中可能包括更新数据,这些数据将通过通常的单向向下数据流更新下游组件。 通过将向下的数据流与向上的数据流分开,可以简化事情,并且数据管理性能良好。

Angular 2组件:输入和输出

在深入研究Angular 2组件之后,让我们看一下可以传递给@Component装饰器以实现向下和向上的数据流的两个属性:“输入”和“输出”。 这些有时会造成混淆,因为在Angular 2 alpha的早期版本中,它们被称为“属性”(用于“输入”)和“事件”(用于“输出”),并且一些开发人员对名称更改的兴趣不强,尽管确实有道理: https : //github.com/angular/angular/pull/4435

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

您可能会从上面的层次结构讨论中猜到“输入”,它指定了可以在组件上设置的属性,而“输出”则标识组件可以触发以将层次结构上的信息发送到其父级的事件。

Angular 2组件:在@Component装饰器中使用输入和输出属性

图1:使用@Component装饰器中的“ inputs”和“ outputs”属性的组件

关于上面的输入和输出,有几件事要注意:

  • 传递给@Components装饰器的“ inputs”属性将“ myname”列为可以接收数据的组件属性。 我们还将“ myname”声明为ParentComp类中的公共属性。 如果不声明,TypeScript编译器可能会发出警告。
  • “输出”属性将“ myevent”列出为ParentComp可以发出的自定义事件,其父级将能够接收该事件。 在ParentComp类中,将“ myevent”声明为,并将其设置为EventEmitterEventEmitter是Angular附带的内置类,为我们提供了管理和触发自定义事件的方法。 注意,我们必须将EventEmitter添加到文件顶部的import语句中。
  • 该组件在视图中显示传入的“ myname”,但是当我们尝试在ParentComp构造函数中访问它时,它尚未定义。 那是因为在渲染视图之前,输入属性才可用,这是在构造函数运行之后发生的。
  • 我们在模板中添加了一个“单击”事件处理程序,该处理程序调用myeventEventEmitter的“ next() ”方法并将要与事件一起发送的数据传递给该方法。 这是沿组件层次结构发送数据的标准模式-使用“ EventEmitter”调用“ next() ”方法。

现在,我们已经研究了如何在组件中定义“输入”和“输出”,让我们看看如何使用它们。 CompDemo组件的模板使用ParentComp组件:

角度2组件:使用ParentComp定义的输入和输出

图2:该组件使用ParentComp定义的输入和输出

使用“ ParentComp”的语法非常简单:

  • [myname] = "myFriend" :这告诉Angular将ParentComp输入属性“ myname”设置为作为CompDemo属性插入的“ myFriend”的值。 注意我们在构造函数中设置了“ myFriend”
  • (myevent) = "handleMyEvent($event)" :这告诉Angular在ParentComp触发“ myevent”时调用CompDemo的“ handleMyEvent($event) ”方法。 我们传递给“数据next()在CompDemo”方法ParentComp可通过传递“ $event ”作为参数传递给“ handleMyEvent() ”方法。

在这两种情况下,属性的左侧都引用ParentComp中的某些内容(输入属性或输出事件),而右侧则引用在CompDemo上下文中解释的内容(实例属性或方法)。

如果您尝试在ParentComp上设置属性而不将其指定为输入属性,则Angular不会抛出错误,但也不会设置该属性。 上面的模式(通过“ input”属性传递数据并通过“ output”事件发送数据)是在Angular 2组件之间共享数据的主要方式。 我们将在以后的文章中看到,我们还可以通过定义可以注入组件的服务来在组件之间共享数据,从而有效地为我们提供了一种在组件之间共享数据或功能的方法。

@Input()和@Output()

可以使用另一种语法来定义组件中的输入属性和输出事件。 在上面的示例中,我们使用了传递给@Component装饰器的对象的“输入”和“输出”属性。 Angular还允许我们使用@Input@Output装饰器来获得相同的结果:

Angular 2组件:使用@Input和@Output装饰器
图3:使用@Input@Output装饰器

在上面的ParentComp版本中,我们省去了@Component定义对象的“ inputs”和“ outputs”属性。 相反,我们在第2行的导入命令中添加了“输入”和“输出”,并在ParentComp类中使用了@Input@Output装饰器来声明“ myname”和“ myevent”。

无论您使用输入/输出还是@Input / @Output ,结果都是相同的,因此,选择使用哪一个在很大程度上是一种风格决定。

结语

在本文中,我们更深入地研究了Angular 2组件,它们之间的关系以及如何向其中传递数据以及如何获取数据。 我们仍然只是从组件的角度出发。 它们可以说是Angular 2的主要功能,并且涉及到设计和构建Angular 2应用程序的各个方面。 在以后的文章中,我们将通过更详细地查看Angular服务来继续探索Angular 2组件,这是一种重用代码和封装关键功能的方法。

Web开发更多动手

本文是Microsoft和DevelopIntelligence的Web开发系列文章的一部分,内容涉及实用JavaScript学习,开源项目以及互操作性最佳实践,包括Microsoft Edge浏览器和新的EdgeHTML呈现引擎

DevelopIntelligence为技术团队和组织提供讲师指导的JavaScript培训AngularJS培训和其他Web开发培训

我们鼓励您使用dev.microsoftedge.com上的免费工具跨浏览器和设备进行测试,包括Microsoft Edge(Windows 10的默认浏览器):

向我们的工程师和福音传教士进行更深入的学习:

我们的社区开源项目:

更多免费工具和后端Web开发人员资料:


本文是Microsoft的Web开发系列的一部分。 感谢您支持使SitePoint成为可能的合作伙伴。

翻译自: https://www.sitepoint.com/angular-2-components-inputs-outputs/

angular 输入输出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值