N。正如上个月提到的,现在可以开始处理 MEAN 堆栈的前端。也就是说,我们将深入探究 Angular。自本文撰写之时起(可能在今后的几年间),我们都会面临一个问题,即 Angular 存在某种版本问题。

Angular 多年来一直是单页面应用程序领域的主流产品。不过,在不断发展的过程中,Angular 已成为一种不同的体系结构范式,导致“新式”Angular 变得与 Angular 向后不兼容。

这就给大部分开发者提出了一个棘手问题: 该使用哪个版本呢?

尽管对于此问题从来没有一个放之四海而皆准的答案,但历史表明,最终选用的还是更高版本(仅有为数不多的例外情况)。

这样一来,就形成了基本的推荐做法: 如果是刚开始处理项目(即所谓的“未开发”项目),且没有要维护或扩展的现有代码,请使用最新最棒的稳定版框架。由于我的应用程序(我一直在开发的扬声器分级门户)绝对属于未开发项目一类,因此在本系列专栏中,我将使用新版 Angular 2(将 Angular 1 视为原始产品)。

当然,很容易就会做出相反的决定。幸运的是,Internet 上有许多不错的 Angular 教程(如果为了让所有 Angular 1 教程编写人员的辛苦工作不白费而选择 Angular 1 的话,那也真够行的)。

不过,我要警告的是,将 Angular 1 应用移植到 Angular 2 更相当于完全重写。所以,请务必在今后规划时将此问题考虑在内。

与此同时,我们将对 Angular 2 进行一些探索。

开始使用

若要使用任何一项新技术,首先需要编写到处可见的“Hello World”。不过,我立即想到在生成 Angular 2“Hello World”应用时有两件有意思的事情,需要在深入探究前讨论。

第一件,使用诸如 Angular 之类的 Web 框架时,安装过程通常非常轻量级,令人难以置信(与安装新的编程语言、IDE 和数据库等相比),因为大多数情况下,实际库本身可以直接从 CDN 或主机服务器中提取。不过,对于大部分开发任务来说,最好是从本地文件系统运行库,因为这是开始使用 Angular 2 时的默认方法,也是我将采用的方法。

第二件,首次运行 Angular 2 时克隆 Git 存储库。也就是说,开始使用时的默认方法是克隆 GitHub 上的现有 Git 存储库,这与 IDE 托管的“项目模板”恰恰相反。 其他语言和框架开始流行采用这种方法。这种方法的优势显而易见,不仅易于理解、无需维护(这一点可能是最重要的),还易于扩展,从而可以添加原始模板没有的其他功能(结构、内容等)。

因此,假定已在计算机上安装 Node.js(关注本系列专栏的读者应已安装),同时通过 Git 请求获取 Angular 2“快速入门”项目:

git clone https://github.com/angular/quickstart.git hello

假定这会连接到 GitHub 并成功克隆项目,现有大量文件驻留在“hello”子目录中。对于简单的“Hello World”应用程序,其实还有很多步骤绝对有必要执行,Angular 团队也承认这一点。在存储库的自述文件中,特别声明了要放置其他许多文件,以从头培养一些好习惯,如对前端代码执行单元测试和端到端 (e2e) 测试。

我们稍后将深入探究这些。现在,扫一眼目录就会发现一些对 MEAN 开发者来说应该比较熟悉的内容:突出显示的 package.json(npm 清单文件)和 tsconfig.json(TypeScript 配置文件)。

回顾一下,从源控件中拉取 Node.js 项目的标准做法是启动依赖项。因此,在执行其他任何操作前,请先拉取依赖项,并通过执行以下命令对项目执行唤醒式调用,然后在浏览器中转到端口 3000(实际上,在该端口运行本地 HTTP 服务器后,脚本通常就会立即为你打开一个端口):

npm installnpm start

然后,就会看到 Web 框架亲切的问候语,如图 1 所示。


图 1:欢迎使用 Angular 2 Web 框架


就其自身而言,知道一切正常运行总是令人高兴,但除此之外程序员还想查看代码。回到运行 HTTP 服务器的命令行管理程序,然后按 Ctrl+C 关闭一切。(或者,打开同一目录的第二个命令行管理程序,哪种方法更容易就选择哪种。)

下面我们来了解一下,好吗?

代码概览

虽然在 Angular 2 应用程序中查找代码的首选位置当然是 index.html 文件,但其实眼下此文件给人带来的更多是困惑(而非帮助);我们暂且不谈这种方法,将在其他地方予以深究。

Angular 团队最先承认“快速入门”的目录结构并不可作为构建代码结构的参考,但通常情况下,所有 Angular 2 应用都包含某种“源”目录(而不是项目的主根),用来驻留应用程序。

(这样一来,可以更轻松地进行捆绑,而无需拉取各种仅供开发者使用的文件,如 package.json。) 在“快速入门”中,此目录被称为“应用”,它包含三个文件:main.ts 以及 app.component.ts 和 app.module.ts(看起来紧密关联的两个文件)。

(请注意,因为 TypeScript 转译器会就地修改这些文件,所以此目录可能不止包含这些文件,但更显而易见的是,所有这些文件都互相关联,例如,main.ts 会生成 main.js 和 main.js.map)。

第一个文件 main.ts 的用途很明确,它是 Angular 2 应用程序的主入口点,而其他两个文件的用途并非那么明确。不过,我们将介绍所有这三个文件。

入口点: Main.ts

main.ts 的内容乍一看有点令人捉摸不透:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

并不完全清晰明了。不过,我们将逐个部分地来了解它。看过我上一期有关 TypeScript 的专栏就会知道,“import”语句会从另一个文件中拉取符号。如你所见,它正在从两个不同的位置导入符号。

第一个语句中的 platformBrowserDynamic 来自 Angular 库的某个位置,因此这可能是启动 Angular 2 环境和库的标准样本。(最后一行代码明确证实了这一点。) 然而,第二个语句从本地文件 app.module 导入,这听上去很像是必须包含你的代码。

大部分情况下,在整个 Angular 2 开发过程中 main.ts 保持不变,与应用程序相关的一切反正都位于模块文件 (app.module.ts) 中,但了解上下文总是非常有用的。

(如果跟踪 index.html 的痕迹,最终会发现通过 System.js 模块加载程序机制加载 main.js 的位置,尽管此时并不推荐这样做。) 也就是说,大部分操作是在 app.module 及其关系中执行。

应用程序模块: App.module.ts

与上一版一样,Angular 2 致力于将应用程序代码模块化为可管理的小块,这样做首先需要将整个应用程序内的元素放到一个位置(Angular 2 将其称为“模块”)。因此,该文件将拉取几个 Angular 2 概念,然后声明应用程序模块,以及反过来使用的内容:

import { NgModule }      from '@angular/core';import { BrowserModule } from '@angular/platform-browser';import { AppComponent }  from './app.component';
@NgModule({imports:      [ BrowserModule ],declarations: [ AppComponent ],bootstrap:    [ AppComponent ]
})export class AppModule { }

再强调一遍,此时全都是 import 语句: 首先,拉取一些与 Angular 2 相关的概念(NgModule 和 BrowserModule),然后导入应用程序组件(我很快就会介绍)。

不过,请注意,NgModule(如我在上一期专栏中所述)本质上是 TypeScript 修饰器,这也是为什么 Angular 2 提供所需的全部功能,同时还允许开发者使用框架专心开发应用程序专有类(本文称为“AppModule”)的应用程序专有功能。

Angular 2 在将代码和功能分入各个模块和组件方面采取强硬立场,了解这一点实际上非常重要。这将是 Angular 2 中不断重复的主题,而在 Angular 1 中,我们可以将代码看作是大致按开发者选择的任意方式排列(但开发者多半是选择根本不进行排列)。

在 Angular 2 中,库强制开发者即时应对组织架构。使用 Angular 2,可以根据需要选择模块和组件的粒度,但毋庸置疑,必须将代码和功能分入各个模块和组件。这就是 Angular 的独到之处,必须予以遵循。

NgModule 修饰器提供此模块的元数据,包括它依赖的其他模块、它导出的声明(我很快就会介绍相应的用法)以及需要执行的启动。NgModule 包含多个选项方便你此时传递,而随着 Angular 2 应用程序越来越复杂,这些选项也会相应增加。为此文件添加书签,因为你将多次回到这里。

Hello World 组件: App.component.ts

最后要介绍的是实际的应用程序组件,它是目前为止唯一一个定义 UI(总之是它的所有代码行)的组件。下面就是 app.component.ts 文件:

import { Component } from '@angular/core';
@Component({selector: 'my-app',template: `<h1>Hello {{name}}</h1>`,
})export class AppComponent  { name = 'Angular'; }

同样,组件依赖 Angular 2 构造(组件修饰器),因此它是从 Angular 库内部的相应位置导入。然后,使用两个参数(选择器和模板)将导出的类 AppComponent 声明为 Angular 组件。

模板的作用很容易理解: 这是应用于声明此组件的 HTML 片段(包括 ECMAScript 字符串内插绑定,在此示例中,为 HTML 中的“name”参数)。

因为此模板有时可能会有点大,或至少比此处指定的一行 HTML 要大,所以除了使用“template”外,还可以使用 templateUrl 来指定用于查找模板的外部文件(将在之后的典型情景中这样做)。

选择器参数更加细微,它声明此组件在 UI 中应用到的位置。实际上,这意味着,只要“my-app”标记在 HTML 中显示,就会应用此组件。到目前为止,还没有看到任何 <my-app> 标记,完全是因为这个特殊的标记是在 index.html 文件内部进行声明(我尚未对此进行介绍):

<!DOCTYPE html>
<html><head><title>Angular QuickStart</title><!-- bunch of other stuff snipped for simplicity --></head><body><my-app>Loading AppComponent content here ...</my-app></body>
</html>

请注意,“my-app”标记括住了一些文本,这主要是占位符文本,可能显示,也可能不显示,具体视浏览器加载和呈现应用程序的速度而定。

总结

生成简单的“Hello World”需要完成大量工作;如果只要直接编写 HTML,省掉剩下的工作,似乎会轻松得多。不过,Angular 的独到之处主要是在组件的基础上生成应用程序(而不光是到处都编写 HTML、CSS 和 JS),此类组织和结构是有开销的。

事实上,到目前为止我所介绍的 90% 基本上都是 Angular 开销。随着应用程序不断变大,开销会按比例缩减,让应用程序开发者可以将全部精力集中在体现应用程序的精髓上。而这恰恰正是应用程序框架应起到的作用。

不过,相关介绍自然尚未完结。Angular 2 还有很多要探索的地方,我们有一个准应用程序有待生成和启动。

在今后的专栏中,我将探索如何创建组件,特别是对扬声器列表执行一些基本的 CRUD(从内存中的“数据库”入手),以及 Angular 2 是如何让一切变得简单易操作的。请耐心等待,未来会有更多精彩内容。在那以前,祝你编码愉快!


Ted Neward 是本部位于西雅图的 Polytechnology 公司的顾问、讲师和导师。他是一位 F #MVP,写过 100 多篇文章,独自撰写并与人合著过十几本书。

如果您有兴趣请他参与您的团队工作,请通过 ted@tedneward.com 与他联系,或通过 blogs.tedneward.com 访问其博客。

衷心感谢以下技术专家对本文的审阅: Ward Bell

原文地址:https://msdn.microsoft.com/zh-cn/magazine/mt793274


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

内容转载自公众号

微软中国MSDN
了解更多

赞赏

使用 Angular相关推荐

  1. Angular No name was provided for external module 'XXX' in output.globals 错误

    Angular 7 开发自定义库时,引用ngZorroAntd,build过程中出现 No name was provided for external module 'ng-zorro-antd' ...

  2. angular.isUndefined()

    <!DOCTYPE html> <html><head><meta charset="UTF-8"><title>ang ...

  3. 五:Angular 数据绑定 (Data Binding)

    通常来说,数据绑定要么是从页面流向组件中的数据,要么是从组件中的数据流向页面.下面我们来介绍在Angular 2中数据绑定的几种不同方式.  1. 使用{{}}将组件中的数据显示在html页面上  实 ...

  4. angular初步认识一

    最近比较流行MVC前端框架开发,最近研究了一个框架AngularJS框架 不说那么多,先上例子,我是个代码控 <!DOCTYPE html> <html lang="en& ...

  5. 【讲人话】Angular如何通过@ViewChildren获取实时渲染的动态DOM节点元素(@ViewChild只能获取静态的固定DOM节点)

    故事背景:有一天,强哥整了个动态渲染的列表代码如下 app.component.html <div><button (click)="add()">添加一行 ...

  6. Angular的ChangeDetectorRef.detectChanges()实现angularJS的$apply()方法,强制刷新数据渲染

    在Javascript代码里,都是按照一定顺序来执行的,当轮到一个代码片段执行的时候,浏览器就只会去执行当前的片段,不会做任何其他的事情.所以有时候一些做得不是很好的网页,当点击了某个东西之后会卡住, ...

  7. Angular多个页面引入同一个组件报错The Component ‘MyComponentComponent‘ is declared by more than one NgModule怎么办?

    有一天,我写了一个自信满满的自定义组件myComponent,在多个页面import使用了,结果控制台给我来这个 我特么裤子都脱了,你给我来这个提示是几个意思 仔细一看 The Component ' ...

  8. 【硬核解说】一口气讲明白Angular的5种路由守卫RouteGuard是嘛玩意儿

    Angular的常用路由守卫有5种,按照执行顺序: ① CanLoad:进入到当前路由的时候触发(若用户没有权限访问,相应的模块并不会被加载.这里是指对应组件的代码). ↓ ② CanAcitivat ...

  9. 浅谈Angular如何自定义创建指令@Directive

    ​知识普及 Angular 指令根据其创建形式分为内置指令和自定义指令,指令按照类型分: 模板指令--组件就是模板指令(只能自定义) 属性型指令 -- 更改元素.组件或其他指令的外观或行为的指令(有内 ...

  10. 【进阶玩法】Angular用emit()实现类似Vue.js的v-model双向绑定[(ngModel)]功能

    app.component.html <app-sizer [(ngModel)]="fontSizePx"></app-sizer> <p [sty ...

最新文章

  1. 中国发展研究基金会联合百度发布智能经济白皮书:新基建是助燃剂,其势已成...
  2. 为了孩子上名校,他们发论文给子女署名,Nature发文报道韩国学术不当行为
  3. leetcode 101. 对称二叉树 递归解法 c语言
  4. YunYang1994/tensorflow-yolov3 ValueError: cannot reshape array of size 43095 into shape (6) 解决办法
  5. 序列中最大的数(51Nod-1062)
  6. 关于在Ubuntu系统中出现Could not get lock /var/lib/dpkg/lock解决方案
  7. 在ubuntu中安装PhantomJS
  8. Flask 应用最佳实践
  9. 纯新手DSP编程--5.31--硬件中断管理
  10. linux文件系统 - 初始化(一)
  11. ns2 java_【NS2】用eclipse调试NS2(转载)
  12. 打谱软件-Avid Sibelius 8.5.0 macOS
  13. ADB的下载安装和基本命令
  14. 沁恒三模键盘方案测试体验
  15. 中国龙与西方龙的区别
  16. ICLR 2022 | 颠覆传统!大规模图像检索系统首次引入「热刷新」模型升级!腾讯清华大学新作...
  17. MVC和MVT框架对比
  18. ubuntu黑屏有声音
  19. 只会用 xxl-job?更强大的新一代分布式任务调度框架来了!
  20. Linux系统换主板后网络,linux 跟换主板后网卡配置.docx

热门文章

  1. 《Network Warrior中文版(第2版)——思科网络工程师必备手册》一3.3 自动协商故障...
  2. 自定义控件详解(四):Paint 画笔路径效果
  3. phpmyadmin的安装部署
  4. 对大数据知识架构的梳理
  5. JMeter基础知识
  6. 重学数据结构004——栈的基本操作及实现(数组实现)
  7. 软件工程心理学之1----开篇
  8. Build 2021 :正式发布.NET 6 Preview4
  9. .NET RulesEngine(规则引擎)
  10. NET问答: 重写了 Equals,还有必要重写 GetHashCode 吗?