网站搜索

typescript - 在 angular2 中修改 url 时仅更改 DOM 的一部分


创建一个用于显示新闻的网页应用,我希望它是一个单页应用,文章以列表形式显示,只显示标题,并且(点击标题时)会展开显示内容。

我已经做过了,但现在我想修改 URL,使它能够适应已打开的文章,而无需重新加载整个页面。我已经按照子路由组件和这里的一些答案操作过,但除此之外没有任何其他效果。

无法找到用于加载的主要出口''

显示在控制台中。代码如下:

app/app.routes.ts :

import { provideRouter, RouterConfig }  from '@angular/router';
import { articlesRoutes } from './articles/articles.routes';
import { ArticlesComponent } from "./articles/articles.component";

const routes: RouterConfig = [
    ...articlesRoutes,
];

export const appRouterProviders = [
    provideRouter(routes)
];

app/articles/articles.routes.ts :

import {ArticlesComponent} from "./articles.component";
import {RouterConfig} from "@angular/router";
import {ArticleDetailComponent} from "./detail/article-detail.component";

export const articlesRoutes: RouterConfig = [
    {
        path: '',
        component: ArticlesComponent,
        children: [
            {
                path: 'detail/:id',  component: ArticleDetailComponent
            },
        ]
    }
];

应用/文章/文章组件.html

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ArticleService } from "./shared/article.service";
import { Article } from "./shared/article.model";
import { ArticleDetailComponent } from "./detail/article-detail.component";
import { ROUTER_DIRECTIVES }  from '@angular/router';

@Component({
    selector: 'fcso-articles',
    templateUrl: 'app/articles/articles.component.html',
    directives: [ROUTER_DIRECTIVES],
    providers: [ArticleService],
})
export class ArticlesComponent implements OnInit {
    articles: Article[] = [];
    articleOpened: Article = null;
    error: any;

    constructor(
        private articleService: ArticleService,
        private router: Router) {}

    getArticles() {
        this.articleService
            .getArticles()
            .then(articles => this.articles = articles)
            .catch(error => this.error = error);
    }

    ngOnInit() {
        this.getArticles();
    }

    //function changing the hidden article and redirecting to URL
    gotoDetail(article: Article) {
        this.articleOpened = article;
        this.router.navigate(['', '/detail', this.articleOpened.id]);
    }
}

index.html

    <body>
      <!-- the main content (from app.component.ts) is not loaded from router -->
      <fcso-main>
        Loading...
      </fcso-main>
    </body>

应用程序/应用程序组件.html

<div class="container">
    <div class="col-xs-12 col-md-8 col-md-offset-2 fcso-no-padding">
        <div class="panel panel-default">
            <div class="panel-body">
                <h1 class="text-center">Title</h1>
            </div>
        </div>
        <!-- this router outlet should show articlesComponent -->
        <router-outlet></router-outlet>
    </div>
</div>

应用/文章/文章组件.html

<div class="panel panel-default" *ngFor="let article of articles">
    <div class="panel-heading fcso-panel-heading" *ngIf="article !== articleOpened" >
        <h3 class="text-center fcso-open-panel" (click)="gotoDetail(article)">{{article.title}}</h3>
    </div>
    <!-- router-outler is hidden to boost angular perfs and avoid troubles -->
    <router-outlet *ngIf="article === articleOpened"></router-outlet>
</div>

我也尝试将 articles.routes.ts 的内容直接移动到 app.routes.ts 中,没有做任何更改。我尝试只在 app.routes.ts 中放置父路由。它可以加载文章列表,但不会加载子内容,并出现以下错误代码:

无法找到用于加载 'ArticleDetailComponent' 的主出口

我尝试在 .component.ts 中使用 routerConfig,也没有影响。

我需要做什么才能在点击的标题位置显示子组件(ArticleDetailComponent)并修改 URL?

答案#1

  • 你在 *ngFor 中创建了 <router-outlet>。没有名字的 <router-outlet> 只能有一个,其他的需要有不同的名字。使用 *ngFor 创建它们会生成任意数量的无名 <router-outlet>,这是无效的。

  • 扩展运算符缺失

const routes: RouterConfig = [
  ... articlesRoutes,
];
  • 对于子路由,缺少默认路由
export const articlesRoutes: RouterConfig = [
  { path: '', component: ArticlesComponent, children: [
    { path: '', redirectTo: 'detail/01', pathMatch: 'full'}, /* required */
    { path: 'detail/:id',  component: ArticleDetailComponent },
  ]}
];

Plunker 示例