AngularJS(版本1.x)是基于JavaScript的开源框架。它是跨平台的,用于开发单页Web应用程序(SPWA)。AngularJS实现了MVC模式以分离逻辑,表示和数据组件。它还使用依赖注入来在客户端应用程序中利用服务器端服务。
Angular(2.x及更高版本)是用于开发前端Web应用程序的基于Typescript的开源框架。Angular具有泛型,静态类型化等功能,还有一些ES6功能。
我们建议学习Angular并将其用于新项目。AngularJS主要用于遗留项目。
学习Angular的最好方法是在YouTube上使用freeCodeCamp的6小时Angular教程。
Angular JS -Angular JS主页
AngularJS样式指南 -Angular开发的详细最佳实践
在Angular JS中进行路由-15分钟内进行客户端路由
Angular ToDo App -12分钟内完成Angular ToDo应用
Egghead.io AngularJS课程($)
Angular -Angular主页
Angular风格指南 -Angular开发的详细最佳实践
指令 -出色的指南,详细介绍了角度指令(第1部分)
Egghead.io角课程($)
FrontendMasters-使用Angular构建Awesomer应用
终极角-托德格言
Angular 6(以前为Angular 2)-完整指南($)MaximilianSchwarzmülle
Google于2010年10月20日发布了AngularJS的初始版本。AngularJS的第一个稳定版本于2017年12月18日发布了1.6.8版。Angular 2.0发布于2014年9月22日在ng-Europe会议上举行。Angular 2.0的功能之一是动态加载。
经过一些修改,Angular 4.0于2016年12月发布。Angular4向后兼容Angular 2.0。HttpClient库是Angular 4.0的功能之一。Angular 5于2017年11月1日发布。对渐进式Web应用程序的支持是Angular 4.0的改进之一。Angular 6已于2018年5月发布。最新的稳定版本是6.1.9。
安装:
我们可以通过引用可用的源代码或下载框架来添加Angular。
链接到源:
AngularJS:我们可以通过引用Google的内容交付网络来添加AngularJS(Angular 1.x版本)。
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
下载/安装:我们可以使用npm,Bower或composer下载该框架。
角1.x:
npm
npm install angular
然后添加<script>
到您的index.html
:
<script src="/node_modules/angular/angular.js"></script>
凉亭
bower install angular
然后添加<script>
到您的index.html
:
<script src="/bower_components/angular/angular.js"></script>
有关文档的更多信息,请参考AngularJS的官方网站。
Angular包含许多用于构建应用程序的示意图。组件就是这样的示意图之一。它们包含与应用程序的单个部分有关的单个逻辑单元。组件通常与其他原理图配合使用以更有效地运行。
在所有原理图中,组件消耗的电流往往比提供的更多。虽然其他示意图(例如指令,管道和服务)提供了实用程序,但组件仍在使用。他们负责应用程序接口,因此使用它们的原因很有意义。
组件简化了应用程序。将逻辑集中到可见界面的单个部分中是他们的主要目标。要逐步构建应用程序,必须逐个构建组件。毕竟,组件是Angular的构建块。
如前所述,组件消耗实用程序(服务/资源)。它们介于业务逻辑和表示之间,以产生一个紧密联系的单元。Angular将各种机制附加到每个组件。这些附件将类识别为组件并定义其标准功能。
Angular在遇到组件时必须识别它们。为此,@Component
必须装饰要用作组件的每个类。装饰器向Angular指示类是什么。
对于组件,它必须知道如何与其注入器进行交互,与模板连接,从样式列表中提取样式,封装其样式等等。Angular负责大多数底层需求。开发人员仍然需要配置组件的行为,导入其依赖项并扩展其逻辑。
对于所有这些事情,我们都有组件的类。班级保持一切相对统一。它封装了组件的业务逻辑。
继续并安装Angular命令行界面(CLI)。您可以从本文中了解更多信息。CLI命令ng generate component [name-of-component]
产生以下内容。
import { Component, OnInit } from '@angular/core';@Component({ selector: 'app-example', templateUrl: './example.component.html', styleUrls: ['./example.component.css']})export class ExampleComponent implements OnInit { constructor() { } ngOnInit() { }}
这是所有重要组成部分的基础骨架。该@Component
装饰是最重要的部分。没有它,上面的示例将成为通用类。Angular依靠装饰器来识别类的示意图类型。
@Component
接收元数据作为单个对象。装饰器只是底层的JavaScript函数。它们与元数据对象一样接受参数。元数据对象配置组件的基本依赖关系。每个字段都扮演一个角色。
selector:
告诉Angular将组件与应用程序模板HTML中的某个元素相关联。
templateUrl:
接受组件模板HTML的文件位置(这是显示数据的位置)。
styleUrls:
接受样式表文件位置(字符串)的数组。这些样式表以组件的分配模板为目标。
将元数据视为一大堆配置。装饰器接受它,以便它可以生成特定于组件的数据。装饰器用其类的行为所需的数据来装饰基础类。是一个组件类。
默认情况下,该类的签名会导出,以便可以导入组件。ngOnInit
也得到实施。implements
告诉类根据接口的定义定义某些方法。ngOnInit
是生命周期挂钩。
组件使用各种工具,服务和功能。组件可用的一项关键功能是生命周期挂钩。每个钩子的解释存在这篇文章中。
总共有八个,它们都充当计时功能。当组件通过更改检测从状态转换为状态时,它们有条件地执行。此过程在组件树中不断发生。它搜索需要重新渲染模板的数据更改。
分手后要往前看了。请参阅上述文章,以获取有关组件生命周期的更多信息。它值得更多的解释。
数据驱动一切。组件也不例外。组件封装了所有数据。要从外部接收数据,组件必须显式声明它。这种形式的隐私可防止信息在组件树之间冲突。
数据确定从组件类显示到其模板的内容。对类数据的任何更新都会(或至少应该)更新模板显示。
组件通常会初始化一组存储数据的成员(或变量)。为了方便起见,在整个组件类逻辑中使用它们。此信息助长了导致模板及其行为的逻辑。请参见以下示例。
// ./components/example/example.component.tsimport { Component, OnInit } from '@angular/core';import { Post, DATA } from '../../data/posts.data';@Component({ selector: 'app-example', templateUrl: './example.component.html'})export class ExampleComponent implements OnInit { username: string; totalPosts: number; allPosts: Post[]; deletePost(index: number): void { this.allPosts.splice(index, 1); this.totalPosts = this.allPosts.length; } ngOnInit(): void { this.username = DATA.author; this.totalPosts = DATA.thePosts.length; this.allPosts = DATA.thePosts; }}
<!-- ./components/example/example.component.html --><h1>{{ username }}</h1><span>Change Name: </span><input [(ngModel)]="username"><h3>Posts: {{ totalPosts }}</h3><ul><hr/><div *ngFor="let post of allPosts; let i=index"> <button (click)="deletePost(i)">DELETE</button> <h6>{{ post.title }}</h6> <p>{{ post.body }}</p> <hr/></div></ul>
注意组件与其数据交互的方式。它首先从../../data/posts.data
开始将其转发到模板进行显示之前获取它。
数据显示在整个模板中。在双花括号内,变量的值从组件类映射到花括号中。*ngFor
遍历allPosts
类数组的循环。单击该按钮可allPosts
从其索引中删除特定元素。您甚至可以username
通过在输入框中输入内容来更改最上面的内容。
上述交互会更改组件类的数据,从而更新组件的模板HTML。组件提供了促进数据流的主干逻辑。模板HTML使该数据对用户可读。
上一个示例的模板HTML具有有趣的语法。该语法不是实际的HTML。这是Angular的模板HTML。有些人通常将其称为HTML Plus,只有Angular的编译器才能识别。编译器支持可动态处理HTML的语法。本文通常将其称为“模板HTML”或“模板”。
该语法使组件可以将数据直接注入模板HTML中。注入是动态的。这意味着数据可以迭代并以HTML形式显示,而无需外部帮助。Angular编译器在到达Web浏览器时将其编译为真实的HTML。
要了解有关数据绑定到模板的某些方式的更多信息,请阅读Angular中的数据绑定。上一个示例({{ ... }}
)中出现了一些数据绑定的示例。对于本文而言,足以识别组件类与其模板之间发生的数据交互。
管理模板状态的数据势在必行。但是,纯数据并不总是能够满足应用程序的预期设计。可能需要与文档对象模型(DOM)进行更直接的交互。
为此,组件必须引用模板元素。当数据更改时,组件可以显式操作DOM。这是一种更具说明性的方法。
组件可以使用Web浏览器的DOM应用程序编程接口(API)来获取引用。坏主意。Angular更喜欢跨平台兼容性。为了使组件在Web浏览器之外运行,需要使用Angular的API而不是DOM的API。
组件可以使用@ViewChild
和ContentChild
装饰器查询其模板。他们代表组件类获取对模板元素的引用。
import { Component, ViewChild, ContentChild, ElementRef, Renderer2, AfterContentChecked, AfterViewChecked } from '@angular/core';@Component({ selector: 'app-child', template: ` <button (click)="toggleEnlarge()">Toggle Enlarge</button> <ng-content></ng-content> `})export class ChildComponent implements AfterContentChecked { @ContentChild("pReference", { read: ElementRef }) pElement: ElementRef; textEnlarge: boolean = false; constructor(private renderer: Renderer2) { } toggleEnlarge() { this.textEnlarge = !this.textEnlarge; } ngAfterContentChecked() { if (this.textEnlarge) this.renderer.setStyle(this.pElement.nativeElement, 'font-size', '25px'); else this.renderer.setStyle(this.pElement.nativeElement, 'font-size', 'initial'); }}@Component({ selector: 'app-parent', template: ` <button (click)="toggleHighlight()">Toggle Highlight</button> <h1 #hOneRefereance>View Child</h1> <app-child> <p #pReference>Content Child</p> </app-child> `})export class ParentComponent implements AfterViewChecked { @ViewChild("hOneRefereance", { read: ElementRef }) hOneElement: ElementRef; textHighlight: boolean = false; constructor(private renderer: Renderer2) { } toggleHighlight() { this.textHighlight = !this.textHighlight; } ngAfterViewChecked() { if (this.textHighlight) this.renderer.setStyle(this.hOneElement.nativeElement, 'background-color', 'yellow'); else this.renderer.setStyle(this.hOneElement.nativeElement, 'background-color', 'initial'); }}
上面的示例包含两个按钮,用于为每个元素切换特定样式。单击按钮可切换每个组件唯一的true / false值。这些布尔值确定自定义样式是否适用。生命周期挂钩(ngAfterViewChecked
和ngAfterContentChecked
)声明性地更改DOM ,而不是这些值引起强制性的更改。
声明式方法通过元素的引用显式更改样式。在命令式编程中,基于数据的DOM更改是隐式的。查看有关命令式和声明式编程的本文以了解更多信息。
需要注意的主要事情是如何从模板中提取这些引用。在示例中,使用两个修饰符查询模板的两个部分:@ViewChild
和@ContentChild
。
它们的区别在于查找元素引用的位置是内容DOM还是视图DOM。这两个DOM存在于ParentComponent的模板中。区分它们很重要,因为它们在不同的时间完成渲染。
这就是为什么@ViewChild
和@ContentChild
同时存在。他们与伴侣的生命周期钩子ngAfterViewChecked
和钩子一起工作ngAfterContentChecked
。这些生命周期挂钩在执行之前等待其各自的查询解决。
一旦解决,@ViewChild
并@ContentChild
提供对两个元素的引用。两者都存在于DOM的不同部分中。布尔数据仍然确定结果。结果如何转换为DOM是与以前的主要区别。DOM是通过对其Renderer2
直接操作进行更新的。
内容DOM存在于ChildComponent <app-child></app-child>
元素的innerHTML中。它们全部位于ParentComponent的模板内。通过将该app-child
项目的innerHTML 项目投影到ChildComponent的模板上<ng-content></ng-content>
。
这例证了内容投影。one
使用模板中another
的标签的innerHTML将组件中的内容显示到另一个组件中,one
以便another
组件可以通过<ng-content></ng-content>
。谢谢您阅读那句话。
因此,为什么ChildComponent <p></p>
使用引用其元素@ContentChild
。<app-child></app-child>
ParentComponent模板中包含的内容构成了内容DOM。ChildComponent通过@ContentChild
查询引用元素。
ParentComponent的视图DOM包含可从组件视图中访问的所有内容。给定的innerHTML,这不一定包括整个模板<app-child></app-child>
。再次,使用来从ChildComponent查询DOM的这一部分@ContentChild
。使用@ViewChild
ParentComponent类查询其他所有内容。
这是组件交换内容和查询其自身内容的一种好方法,而与它们的DOM类型无关。组件也可以使用数据绑定与自己和其他人进行通信。从本文中阅读有关它的更多信息。
样式对于组件的可读性和交互性至关重要。每个组件都封装了其样式表依赖性。这样,它们仅适用于组件的模板HTML。HTML的影子DOM引入的一种特殊技术使这成为可能。
影子DOM分支可以存在于任何元素上。从HTML的源代码中看不到DOM的这一部分。标准HTML元素利用阴影DOM提供其商标外观。影子DOM分支必须将其自身锚定到可见组件,以便它可以设置样式和自定义组件。
影子DOM分支的独特之处在于其封装。用来样式化影子DOM分支的根元素的所有内容都是私有的。没有其他元素可以访问它。
Angular包含这种与组件封装的形式。样式表和组件模板封装在一起。没有其他组件可以访问它们。样式表冲突不会发生。
默认情况下,Angular不使用影子DOM。它使用模拟影子DOM行为的仿真系统。这是一种临时措施,因为某些Web浏览器尚不支持影子DOM API。
该@Component
元数据包含的encapsulation
领域。这使开发人员可以在模拟的影子DOM和实际的影子DOM之间切换,也可以不在两者之间切换。以下是各个选项的顺序:
ViewEncapsulation.Emulated
-伪影DOM(默认)
ViewEncapsulation.Native
-真正的影子DOM(自Angular 6.0.8起不推荐使用)
ViewEncapsulation.None
-都不
ViewEncapsulation.None
表示组件的样式表提升到全局范围。不建议考虑组件应该形成自己的私有单元(封装)。Angular仍然为极端情况提供了逃生门。
组件构建应用程序。除非另行配置,否则它们是私有范围的并且彼此独立统一。应用程序倾向于从根模块开始。除此之外,组件形成一个细长的树,定义了应用程序的其余部分。
组件覆盖了应用程序接口的指定单元。这包括其样式,逻辑和布局。其他原理图(例如管道,服务和指令)在组件代码中经常使用。您可以在其他一些Angular指南文章中了解有关这些交互的更多信息。
不要忘记组件必须自举。这可能发生在根模块或组件的元数据中。这样,Angular可以识别组件在应用程序中出现的任何位置。
您总是可以学到更多,因为组件的深度远远超出了本文所传达的范围。