Web-Angular中的Multiple components多个组件

多个组件的使用(Using multiple components)

        随着应用程序变得更加复杂,我们需要将代码拆分成多个组件。请记住,组件控制着屏幕上的特定区域。它们还可以用于指定整个屏幕,从而允许我们在应用程序中切换不同的页面。在本节中,我们将介绍可以引入的多个组件。我们还将学习如何使用Angular路由器在视图之间进行导航。

        当我们首次讨论组件时,我们注意到组件负责由组件中指定的HTML标签表示的视图。当我们有多个组件和多个视图时,我们需要指定每个视图标签。有两种方法可以组合这些标签。

  1. 一个组件的标签可以嵌套在另一个组件的模板中,
  2. 使用Angular路由器将组件映射到URL字符串,并插入同一个标签中。

        将一个视图嵌套在另一个视图中的一个简单示例如下。假设我们有一个主组件,定义如下:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
             <h1>Embedded component</h1>
             <embedded-comp></embedded-comp>
            `,
})

export class AppComponent { }

        注意,<embedded-comp>标签不是标准的HTML标签。我们可以定义一个新的组件来负责这个标签定义的视图,如下所示:

import { Component } from '@angular/core';

@Component({
  selector: 'embedded-comp',
  template: `<p>This is an embedded text </p>`,
})

export class SecondComponent { }

        请注意,选择器现在是嵌入在主组件中的<embedded-comp>标签。

        我们还没有完成。我们还必须在主模块文件(app.module.ts)中链接这两个定义,如下所示:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { SecondComponent} from './second.component';

@NgModule({
  imports: [ BrowserModule],
  declarations: [ AppComponent,  SecondComponent ],
  bootstrap: [ AppComponent ]
})

export class AppModule { }

        在app.component.ts文件中的添加部分以加粗字体显示。第一个添加的是Typescript导入语句,用于包含SecondComponent类的定义。第二个添加的是将SecondComponent添加到声明列表中,以允许Angular在运行时将其纳入定义中。为了增加趣味性,这个简单的应用程序将如下显示。

Angular 路由器(The Angular router)

        Angular 路由器是 Angular 中的一个功能,允许在多页面应用程序中导航到不同的页面。它将组件映射到特定的 URL,并将它们插入到其他组件中。

        在上面的示例中,我们首先有一个简单的页面,使用路由器将第二个页面/组件插入到标题下方。要配置路由器,我们将 <base href="/"> 标签添加到 index.html 文件的 <head> 标签中。这将设置应用程序期望的基本 URL。

        接下来,我们设置我们的主要 AppComponent 组件如下:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `<h1>路由器示例</h1>
             <a routerLink="/page2">第二页</a>...
             <router-outlet></router-outlet>
            `
})

export class AppComponent { }

        这里有两行是新的内容:

  1. 链接标签有一个 routerLink 属性,指定要插入的页面的相对 URL。路由器定义了相同的属性,可以附加到按钮和其他控件上。
  2. <router-outlet> 标签是路由器预定义的标签,用于指示页面应该插入到何处。新页面将在此标签后插入。

        我们可以定义一个简单的第二页,插入到主页中。定义如下:

import { Component } from '@angular/core';

@Component({
  template: `<p>这是第二页</p>
             <button routerLink="/">返回首页</button>
            `
})

export class Page2Component { }

        请注意,我们已经添加了另一个 routerLink 属性给按钮,以允许用户导航回主页。

        为了将所有内容链接在一起,我们需要更新主模块,导入路由器模块并链接第二页。新的 app.module.ts 如下所示。

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { Page2Component} from './page2.component';

const myRoutes: Routes = [
  {path: 'page2', component: Page2Component}
];

@NgModule({
  imports: [ BrowserModule, RouterModule.forRoot(myRoutes) ],
  declarations: [ AppComponent, Page2Component  ],
  bootstrap: [ AppComponent ]
})

export class AppModule { }

        新的代码用粗体标记。请注意以下几点:

  1. 我们需要导入路由器模块,因为它不在 Angular 核心库中。我们还导入一个称为 Routes 的类,允许我们定义应用程序所有 URL 的行为。
  2. 在此示例中,我们将应用程序的路由定义为一个常量。这不是强制性的,但在添加更多路由时,它将让代码更清晰。
  3. 路由是一个 JavaScript 对象数组。此对象中的路径选择器指定了相对 URL,不包括前导斜杠 "/”。组件选择器指定了要用于此 URL 的组件。
  4. Angular 的导入语句使用 RouterModule.forRoot() 方法来初始化路由,用于在路由器模块中的应用程序。
  5. 我们还导入 Page2Component 类(TypeScript 导入),并声明生成的 Angular 组件,以便可以在所有链接的组件中使用它。

        点击链接后,应用程序如下所示。

(图片的代码为英文,上面代码为了突出文本,把原英文的文本换成了中文)

        我们可以通过向组件添加另一个链接来轻松添加另一页(Page3)。

<a routerLink="/page2">Page 2</a>...
<a routerLink="/page3">Page 3</a>

        我们需要更新app.module.ts来连接所有代码。加粗的文字是额外的代码。

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { Page2Component} from './page2.component';
import { Page3Component} from './page3.component';

const myRoutes: Routes = [
  {path: 'page2', component: Page2Component},
  {path: 'page3', component: Page3Component}
];

@NgModule({
  imports: [ BrowserModule, RouterModule.forRoot(myRoutes) ],
  declarations: [ AppComponent, Page2Component, Page3Component ],
  bootstrap: [ AppComponent ]
})

export class AppModule { }

        我们可以使用路由链接添加一个有用的页面,以便在URL不正确时显示。由于用户可以在浏览器中输入任何URL,我们可以让Web服务器处理常规的404错误,或者引入我们自己的错误页面。在Angular的测试环境中,非法的URL实际上将导致路由器运行时错误。

        我们将非法的URL与以下内容匹配,以添加到Routes数据结构中。

const myRoutes: Routes = [
  {path: 'page2', component: Page2Component},
  {path: 'page3', component: Page3Component},
  {path: '**', component: PageNotFoundComponent}
];

        我们可以创建一个简单的错误消息在一个新的PageNotFoundComponent组件中。

import { Component } from '@angular/core';

@Component({
  template: `<h2>页面未找到!</h2>
             <button routerLink="/">首页</button>
            `
})

export class PageNotFoundComponent { }

        现在,如果我们尝试输入URL“/page4”,我们将收到以下显示结果。

(图片的代码为英文,上面代码为了突出文本,把原英文的文本换成了中文)

        很遗憾,我们引入了一个新的问题,通配符URL也将匹配默认URL。在路由器匹配通配符之前,我们需要显式地路由默认URL。路由器按顺序处理Routes数据结构,因此我们需要将通配符放在路由列表的末尾。

        现在,我们可以指定一个新的空白组件,或者更有用的是一个"帮助"组件,如下所示:

{path: ‘’, component: HelpComponent, pathMatch: ‘full’}

        请注意路由对象中的pathmatch:'full’的添加。这是必要的,以指示空白URL应完全为空白。另一个选项是pathmatch:‘prefix’,在这种情况下,它将匹配所有URL字符串。

        我们将借此机会演示重定向路由的用法。我们可以通过更新路由将默认URL重定向到HelpComponent,同时引入一个帮助组件,如下所示:

const myRoutes: Routes = [
{path: ‘page2’, component: Page2Component},
{path: ‘page3’, component: Page3Component},
{path: ‘help’, component: HelpComponent},
{path: ‘’, redirectTo:“/help”, pathMatch: ‘full’}
{path: ‘**’, component: PageNotFoundComponent}
];

        一个简单的HelpComponent可以如下所示:

import { Component } from ‘@angular/core’;

@Component({
template: <p> 选择一个页面链接 </p>
})

export class HelpComponent { }

        当输入默认URL时,它将显示如下:

        有一个最后的路由器功能我们将看一下,即能够对更复杂的应用程序进行 URL 模式匹配。我们仅仅看一个非常简单的模式匹配。

        以下的路由使用了参数语法。

{path: ‘params/:id’, component: ParamsComponent}

        字符串“:id”引入了一个名为“id”的参数。在我们的例子中,它会跟随斜杠“/”分隔符。

        现在更复杂的问题是要在组件中提取参数。在这种情况下,我们可以将 ParamsComponent 定义如下。

import { Component } from ‘@angular/core’;
import { ActivatedRoute, Router, Params } from ‘@angular/router’;

@Component({
selector: ‘app-root’,
template: <h2>Parameter example</h2> <p>The parameter was {
   
   {param}}.<p> <button routerLink="/">Home</button>
})

export class ParamsComponent {
param: string;
constructor(private route: ActivatedRoute, private router: Router) {}
ngOnInit() {
this.param = this.route.snapshot.params[‘id’];
}
}

        请注意以下代码属性:

  1. 我们必须从 Angular 路由器库中导入参数处理类。
  2. 构造函数定义了两个可注入的服务,ActiveRoute 和 Router。你会记得这是 Angular 在组件中使用 Angular 可注入服务的方式。
  3. 我们使用 ngOnInit() 钩子在组件第一次初始化时执行代码。
  4. 钩子中的代码允许我们在组件初始化时提取 ‘id’ 参数。

        在这里我们应该注意到,这个代码其实是一个非常简单的参数传递版本。一个真正的应用程序可能需要考虑从 web 服务器加载页面时的延迟,并引入一些延迟处理。我们将单独讨论这些问题。

        下面的图片显示了带有字符串"23abc"作为参数的应用程序。请注意它在 URL 地址栏和在组件中显示的文本中都出现了。

        请注意任何有效的 URL 字符串都可以作为参数。如果你想要一个数字参数,那么你可能需要将字符串转换成数字。

猜你喜欢

转载自blog.csdn.net/qq_54813250/article/details/133823792