Typescript 在angular2中修改url时只更改dom的一部分

Typescript 在angular2中修改url时只更改dom的一部分,typescript,angular,angular2-routing,Typescript,Angular,Angular2 Routing,创建一个web应用程序来显示一些新闻,我希望它是一个单页应用程序,其中文章显示为列表,仅显示标题,并且(单击标题时)打开以显示内容 我已经这样做了,但现在我想修改url,使其适应打开的文章,而不必重新加载整个页面。我已经遵循了子路由组件和一些答案,但是没有任何其他情况会发生 找不到要加载“”的主出口 显示在控制台中。代码如下: app/app.routes.ts: import { provideRouter, RouterConfig } from '@angular/router'; im

创建一个web应用程序来显示一些新闻,我希望它是一个单页应用程序,其中文章显示为列表,仅显示标题,并且(单击标题时)打开以显示内容

我已经这样做了,但现在我想修改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)
];
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
            },
        ]
    }
];
app/articles/articles.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)
];
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
            },
        ]
    }
];
app/articles/articles.component.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]);
    }
}
<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>
<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>
index.html

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

加载。。。
app/app.component.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]);
    }
}
<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>
<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>

标题
app/articles/articles.component.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]);
    }
}
<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>
<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?

  • 您可以在
    *ngFor
    中创建
    。只有一个
    没有名称,其他的必须有不同的名称。使用
    *ngFor
    创建它们会创建任意数量的无名
    ,这是无效的

  • spread运算符丢失

  • 对于子路由,缺少默认路由

您能否删除
中的
*ngIf
?它可能会干扰角形路由器的工作方式。它不会改变任何东西。当我在孩子身上犯了错误时,我试过了,但仍然没有改变任何事情。我想这是因为articles.component.ts=>gotoDetail(),它在调用路由器之前显示了路由器出口。谢谢您的回答。我不得不说,我已经在stack overflow中读到了一个名称(用于)的建议,但我记得它不在这个版本的angular routing中。另外,它不在官方文件上,所以,我应该使用选择器吗?关于您对所需元素的建议(最后一点)。它会不会通过调用“ArticleDetailComponent”阻止使用我的“ArticlesComponent”中的内容?它被称为aux routes,它有一些有限的支持,但有几个bug应该在下次更新时修复。“必需”选项,因此在加载页面时没有任何路径,不会导致错误。您也可以使用
component:DummyComponent
而不是
重定向到:“…”
,在这种情况下不显示任何内容。