Multiple components in Web-Angular

Using multiple components

        As applications become more complex, we need to split the code into components. Remember that components control specific areas of the screen. They can also be used to specify the entire screen, allowing us to switch between different pages in the application. In this section, we'll cover several components that can be introduced. We will also learn how to use Angular Router to navigate between views.

        When we first discussed components, we noticed that components are responsible for views represented by the HTML tags specified in the component. When we have multiple components and multiple views, we need to specify each view label. There are two ways to combine these tags.

  1. A component's tags can be nested within another component's template,
  2. Use Angular Router to map the component to a URL string and insert it into the same tag.

        A simple example of nesting one view within another view is as follows. Let's say we have a main component defined as follows:

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

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

export class AppComponent { }

        Note that <embedded-comp>the tags are not standard HTML tags. We can define a new component to be responsible for the view defined by this tag, as follows:

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

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

export class SecondComponent { }

        Note that the selector is now a tag embedded in the main component <embedded-comp>.

        We're not done yet. We must also link these two definitions in the main module file (app.module.ts) as follows:

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 { }

        Added sections in the app.component.ts file are shown in bold font. The first thing added is a Typescript import statement that contains the definition of the SecondComponent class. The second addition is to add SecondComponent to the declaration list to allow Angular to include it in the definition at runtime. To add to the fun, this simple application will look like this.

The Angular router

        Angular Router is a feature in Angular that allows navigation to different pages in multi-page applications. It maps components to specific URLs and inserts them into other components.

        In the above example, we have a simple page first and use router to insert a second page/component below the header. To configure the router, we  <base href="/"> add the tag to the index.html file  <head> . This will set the base URL that the application expects.

        Next, we set up our main AppComponent as follows:

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

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

export class AppComponent { }

        There are two new lines here:

  1. The link tag has an  routerLink attribute that specifies the relative URL of the page to be inserted. Routers define the same properties and can be attached to buttons and other controls.
  2. <router-outlet> Labels are predefined labels on the router that indicate where the page should be inserted. A new page will be inserted after this tag.

        We can define a simple second page and insert it into the home page. The definition is as follows:

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

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

export class Page2Component { }

        Note that we've added another  routerLink attribute to the button to allow the user to navigate back to the home page.

        In order to link everything together we need to update the main module, import the router module and link the second page. The new app.module.ts looks like below.

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 { }

        New code is marked in bold. Please note the following points:

  1. We need to import the router module since it is not in the Angular core library. We also import a class called Routes that allows us to define the behavior of all URLs in our application.
  2. In this example, we define the application's route as a constant. This is not mandatory, but it will make the code clearer when adding more routes.
  3. A route is an array of JavaScript objects. The path selector in this object specifies a relative URL, excluding the leading slash "/". The component selector specifies the component to use for this URL.
  4. Angular's import statement uses the RouterModule.forRoot() method to initialize routing for applications in the router module.
  5. We also import the Page2Component class (TypeScript import) and declare the generated Angular component so that it can be used in all linked components.

        After clicking the link, the application looks like this.

(The code of the picture is in English. In order to highlight the text, the above code replaces the original English text with Chinese)

        We can easily add another page (Page3) by adding another link to the component.

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

        We need to update app.module.ts to connect all the code. Bold text is additional code.

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 { }

        We can use routing links to add a useful page to display when the URL is incorrect. Since the user can enter any URL into the browser, we can let the web server handle regular 404 errors, or introduce our own error page. In Angular's test environment, illegal URLs will actually cause router runtime errors.

        We match illegal URLs with the following to add to the Routes data structure.

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

        We can create a simple error message in a new PageNotFoundComponent component.

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

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

export class PageNotFoundComponent { }

        Now, if we try to enter the URL "/page4", we will receive the following display.

(The code of the picture is in English. In order to highlight the text, the above code replaces the original English text with Chinese)

        Unfortunately we have introduced a new issue, wildcard URLs will also match the default URL. Before the router can match wildcards, we need to explicitly route the default URL. Routers process the Routes data structure sequentially, so we need to put the wildcard at the end of the route list.

        Now we can specify a new blank component, or more usefully a "help" component, like this:

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

        Please note the addition of pathmatch:'full' in the route object. This is necessary to indicate that blank URLs should be completely blank. Another option is pathmatch:'prefix', in which case it will match all URL strings.

        We'll take this opportunity to demonstrate the use of redirect routing. We can redirect the default URL to the HelpComponent by updating the route and introducing a help component as follows:

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

        A simple HelpComponent could look like this:

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

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

export class HelpComponent { }

        When the default URL is entered, it will appear as follows:

        One final router feature we'll look at is the ability to do URL pattern matching for more complex applications. We're just looking at a very simple pattern match.

        The following routes use parameter syntax.

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

        The string ":id" introduces a parameter named "id". In our case, it will be followed by a slash "/" delimiter.

        Now the more complicated problem is to extract the parameters in the component. In this case, we can define ParamsComponent as follows.

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’];
}
}

        Please note the following code properties:

  1. We have to import the parameter handling class from the Angular router library.
  2. The constructor defines two injectable services, ActiveRoute and Router. You'll remember this is how Angular uses Angular injectable services in components.
  3. We use the ngOnInit() hook to execute code when the component is first initialized.
  4. The code in the hook allows us to extract the 'id' parameter when the component is initialized.

        We should note here that this code is actually a very simple parameter passing version. A real application might need to account for delays in loading pages from the web server and introduce some latency handling. We will discuss these issues separately.

        The image below shows an application with the string "23abc" as a parameter. Notice that it appears in both the URL bar and the text displayed in the component.

        Please note that any valid URL string can be used as a parameter. If you want a numeric parameter, then you may need to convert the string to a number.

Guess you like

Origin blog.csdn.net/qq_54813250/article/details/133823792