在之前的教程中,我们对Angular JS进行了很好的介绍,甚至使用Angular命令行界面来启动和运行一个项目。在本教程中,我们将更仔细地研究Angular应用程序的代码执行以及构成Angular组件的文件。首先,我们将把Bootstrap作为一个依赖项添加到我们的项目中,这样我们就可以马上得到一些快速和简单的造型。在我们的Angular项目根部的命令行,我们可以输入以下内容。
hello-angular $npm install --save bootstrap
这个加载到项目中,现在它是一个在 **package.json**中的一个依赖项,我们可以在这里看到。
{
"name": "hello-angular",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "~7.0.0",
"@angular/common": "~7.0.0",
"@angular/compiler": "~7.0.0",
"@angular/core": "~7.0.0",
"@angular/forms": "~7.0.0",
"@angular/http": "~7.0.0",
"@angular/platform-browser": "~7.0.0",
"@angular/platform-browser-dynamic": "~7.0.0",
"@angular/router": "~7.0.0",
"bootstrap": "^4.1.3",
"core-js": "^2.5.4",
"rxjs": "~6.3.3",
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.10.0",
"@angular/cli": "~7.0.4",
"@angular/compiler-cli": "~7.0.0",
"@angular/language-service": "~7.0.0",
"@types/node": "~8.9.4",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~3.0.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.11.0",
"typescript": "~3.1.1"
}
}
配置angular.json以使用Bootstrap
通过添加Bootstrap作为一个依赖项,我们现在可以实际配置Angular来使用这些文件。要做到这一点,我们打开 angular.json文件,在 "样式 "部分添加我们想使用的bootstrap css文件的路径。
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"hello-angular": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/hello-angular",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "hello-angular:build"
},
"configurations": {
"production": {
"browserTarget": "hello-angular:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "hello-angular:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.css"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"hello-angular-e2e": {
"root": "e2e/",
"projectType": "application",
"prefix": "",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "hello-angular:serve"
},
"configurations": {
"production": {
"devServerTarget": "hello-angular:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "hello-angular"
}
Angular组件构建块
一个Angular组件开始是在Typescript中创建的一个类。它有代表可以在视图或模板中使用的数据的属性。它也可以有方法来计算任何需要的商业逻辑。模板是组件的用户界面部分,它是用html编写的,决定了页面上看到的内容。

测试app.component.html中的一些标记
让我们看看Bootstrap样式是否在我们的Angular应用程序中生效了。为此,让我们打开app.component.html文件,添加一些简单的Bootstrap标记,这些标记是我们在Bootstrap网站的例子中发现的。
<div class="jumbotron">
<div class="container">
<h1 class="display-3">Hello, world!</h1>
<p>This is a template for a simple marketing or informational website. It includes a large callout called a
jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more »</a></p>
</div>
</div>
现在,让我们用以下命令来启动我们的Angular应用程序 ng serve命令启动我们的Angular应用程序。

当我们在浏览器中访问http://localhost:4200/,风格设计确实已经生效了

AngularJS中的index.html
在AngularJS中,当应用程序运行时,会提供index.html文件。在我们的单页应用程序中,这就是被提供的单页。你会注意到,我们实际上把上面的html代码放在一个名为app.component.html的文件中。那么,当我们在浏览器中加载index.html页面时,这些HTML代码是如何显示的呢?Angular CLI创建了****作为应用程序的根组件。正是这个组件将整个Angular应用程序联系起来。我们可以在这里看到index.html中的这个标记。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>HelloAngular</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
一个组件有几个文件
在Angular中,每个组件都有几个与它相关的文件。在src/app目录下,我们可以看到命令行界面为我们创建的所有文件,以构建主****组件。

检查app.component.ts
Angular看的第一件事是app.component.ts文件中的选择器属性。注意,这里是一个字符串值 "app-root"。因此,当Angular加载这个组件时,它会寻找一个与'app-root'字符串相匹配的标签,然后用这个渲染的组件替换该标签。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
}
检查main.ts
如果index.html文件是Angular应用程序的主要占位符,那么main.ts文件就是Angular脚本引擎启动的地方。
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
根据上述文件,对Angular如何启动的快速总结如下。
- Angular从main.ts开始
- 使用app.module.ts作为参数来启动应用程序
- 这个模块指定在启动时寻找AppComponent。
- 然后Angular查看该组件并找到app-root选择器
- 最后,当index.html加载时,
<app-root></app-root>被替换成渲染的组件。
组件
组件是Angular的一个关键功能。每个组件都有自己的模板、自己的HTML标记、自己的样式以及自己的业务逻辑。VueJS用一种很好的方式将所有这些功能包装成所谓的单文件组件。在Angular中,我们把这些职责放在不同的文件中。组件允许开发者将复杂的网页分割成可重用的部分。通过这种方法,你可以一次性创建业务逻辑,然后随心所欲地使用它。
创建你自己的组件
为了更好地理解Angular组件的文件结构,我们现在可以去创建一个。现在,我们已经介绍过的应用程序组件是有点特别的。它是整个单页应用程序的根元素,因此在index.html文件中有一个选择器。我们创建的新组件在index.html文件中不会有自己的选择器,但会被添加到app.component.html文件中。
在/app下添加一个子文件夹
为了开始构建一个新的Angular组件,我们将在/app文件夹下添加一个新的文件夹来存放与新组件相关的任何文件。我们可以想象我们正在监控网络上的一些虚拟机。所以我们将创建一个虚拟机组件。这意味着我们需要一个虚拟机文件夹来存放我们的组件文件。

创建组件的typescript文件
创建了我们的文件夹后,我们现在可以添加一个名为virtual-machine.component.ts的文件。

创建组件模板文件
除了我们刚刚创建的Typescript文件外,我们还需要创建相关的模板文件。这通常会是相同的命名方式,但有一个html后缀。所以我们也可以在同一个文件夹中创建virtual-machine.component.html文件。
为你的组件定义TypeScript类
现在可以开始构建组件了,但我们从哪里开始呢?在Angular中,你可以把组件看作是面向对象编程中的类。在Angular中,它是一个Typescript类,然后Angular会根据需要将其实例化。我们可以在virtual-machine.component.ts文件中放置以下代码。
import { Component } from "@angular/core";
@Component({
selector: 'app-virtual-machine',
templateUrl: './virtual-machine.component.html'
})
export class VirtualMachineComponent {}
在上面的片段中,我们现在已经创建了VirtualMachineComponent类,它被导出了,所以可以在其他地方使用。注意该类的命名规则。它是组件本身的名字,后面是Component这个词。现在,Angular知道这是一个组件的方式是通过使用@Component装饰器。这个装饰器接受一个对象,其中的键/值对是这个组件的配置选项。注意这个 **selector属性被设置为 "app-virtual-machine"。这就是我们如何识别和使用这个组件。换句话说,我们现在可以在模板文件中使用**引用这个组件。该 **templateUrl**属性被用来指向包含该组件标记的html文件。首先,我们可以在我们的模板文件中为这个组件设置这个简单的标记。
virtual-machine.component.html
<h1>The Virtual Machine Component</h1>
同时注意virtual-machine.component.ts文件顶部的导入语句。组件装饰器不是TypeScript自动知道的东西。当添加导入语句时,我们把我们想要导入的东西的名字放在大括号**{ }**之间。我们想要访问组件装饰器,这就是为什么我们看到 { Component }.它被从angular核心包中导入。有了这个,@Component装饰器对typescript是可用的,所以当文件被编译为JavaScript时,它可以正确地进行编译。
-
Angular组件类的关键点
-
选择一个好的名字。它既是类的名称,也是组件的名称。
-
使用PascalCasing。这意味着名字中的每一个字都是大写的。
-
YourCoolComponent。在类名后面加上 "组件 "是很常见的。
-
export关键字
-
export关键字使得该类可以在应用程序的其他地方被导入。
-
数据被存储在类的属性中
-
使用正确的数据类型。
-
如果需要的话,设置一个默认值。
-
遵循camelCase惯例。
-
逻辑在方法中
-
在用于添加逻辑或执行组件操作的方法上使用camelCase。
注册我们的新组件!
你可能很想立即投入使用你的新组件在你这样做之前,你需要告诉Angular这个新的组件,并且它已经可以使用了。要做到这一点,必须在app.module.ts文件中注册该组件。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { VirtualMachineComponent } from './virtual-machine/virtual-machine.component';
@NgModule({
declarations: [
AppComponent,
VirtualMachineComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
上面强调的对app.module.ts文件的补充将向Angular注册我们的新组件。我们可以看到,在声明数组中,已经有一个AppComponent被注册。要添加我们的新组件,我们只需添加一个逗号,然后添加我们的组件的名称,即VirtualMachineComponent。除了在声明数组中加入我们的组件名称外,我们还需要导入这个组件,正如我们在高亮行中看到的那样。
尝试新的组件
我们知道,任何新的组件都不能直接在Angular应用程序的index.html文件中使用。然而,我们可以在已经存在的AppComponent中使用它们。让我们打开app.component.html文件,为我们新创建的组件添加一个引用。
<div class="jumbotron">
<div class="container">
<app-virtual-machine></app-virtual-machine>
</div>
</div>
现在在后台我们仍然有ng service在运行。如果你在命令行中检查,你可能会看到应用程序正在重新编译,因为我们已经做了这些新的更新。

当访问浏览器时,我们新创建的组件被渲染到了屏幕上。非常好!

AngularJS组件教程总结
组件的概念存在于所有流行的前端框架中。作为开发者,我们的目标是创建可重复使用的业务逻辑和设计展示的重点容器。这是以组件的形式实现的。通过Angular,我们了解到整个应用程序的根组件是**。**这是在第一次使用Angular CLI构建你的Angular应用程序时为你创建的。我们不想直接修改这个组件,但是我们可以创建新的组件,这些组件可以在包含的app-root组件里面被引用。为了做到这一点,我们采取了以下步骤。
- 使用新组件的名称创建一个新的文件夹
- 在这个文件夹中使用该组件的名称添加一个Typescript文件
- 添加一个HTML模板文件,该文件也使用该组件的名称
- 使用@Component装饰器来配置该组件
- 在模板文件中添加html标记
- 在app.module.ts的声明数组中注册新的组件
- 使用来使用这个新组件。