angular2 – 通过使用路由器的问题

首先,我是一个完整的初学者,使用nodejs,angular2和typescript编程。 基本上我开始阅读在https://angular.io/docs/ts/latest/guide/forms.html和https://angular.io/docs/ts/latest/guide/router.html#!#base-href用新的页面扩展我的应用程序。 我使用mdl在我的应用程序上使用材质组件。
angular2似乎手工重新加载和路由不同,所以我得到以下问题:
路由
重装
我尝试unterstand发生了什么事情,有人可以解释我在angular2中重新加载和路由之间的区别,以及我可以如何适应重新加载行为的路由处理?

更新#1:
index.html的:

<!doctype html> <html> <head> <meta charset="utf-8"> <title>Title</title> <script defer src="/assets/js/material.min.js"></script> <link rel="stylesheet" href="/assets/css/font-awesome.min.css"> <link rel="stylesheet" href="/assets/css/material.min.css"> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> <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><md-spinner></md-spinner></app-root> </body> </html> 

app.module.ts

 import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { AppComponent } from './pages/layout/app.component'; import { HomeComponent } from './pages/home/app.component'; import { LoginComponent } from './pages/myaccount/login.component'; import { NotFoundComponent } from './pages/error/404.component'; import { RegisterComponent } from './pages/myaccount/register.component'; import { RouterModule, Routes } from '@angular/router'; import { LoginService } from './service/LoginService'; const appRoutes: Routes = [ { path: '', component: HomeComponent }, { path: 'series', component: AppComponent }, { path: 'login', component: LoginComponent }, { path: 'register', component: RegisterComponent }, { path: '**', component: NotFoundComponent } ]; @NgModule({ declarations: [ AppComponent, LoginComponent, HomeComponent, RegisterComponent, NotFoundComponent ], imports: [ BrowserModule, FormsModule, HttpModule, RouterModule.forRoot(appRoutes) ], providers: [LoginService], bootstrap: [AppComponent] }) export class AppModule { } 

register.html:

 <div class="mdl-grid iv-padding" > <div class="mdl-layout-spacer"></div> <div class="mdl-cell mdl-cell--4-col"> <div style="text-align:center;"> <form (ngSubmit)="onSubmit()"> <div class="iv-card-wide mdl-card mdl-shadow--2dp"> <div class="mdl-card__title"> <h2 class="mdl-card__title-text">Registrierung</h2> </div> <div class="mdl-card__supporting-text"> <div class="text-field mdl-textfield mdl-js-textfield"> <input class="mdl-textfield__input" required [(ngModel)]="model.username" name="username" type="text" id="username"> <label class="mdl-textfield__label" for="username" >Username</label> </div> <br /> <div class="text-field mdl-textfield mdl-js-textfield"> <input class="mdl-textfield__input" [(ngModel)]="model.password" name="password" type="password" id="password"> <label class="mdl-textfield__label" for="password">Password</label> </div> <br /> <div class="text-field mdl-textfield mdl-js-textfield"> <input class="mdl-textfield__input" [(ngModel)]="model.email" name="email" type="email" id="email"> <label class="mdl-textfield__label" for="email">E-Mail</label> </div> </div> <div class="mdl-card__actions mdl-card--border"> <button type="submit" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">Registrieren</button> </div> </div> </form> </div> </div> <div class="mdl-layout-spacer"></div> </div> 

RegisterComponent

 import { Component } from '@angular/core'; import { User } from '../../objects/user'; @Component({ selector: 'app-root', templateUrl: './register.component.html', styleUrls: ['./register.component.css'] }) export class RegisterComponent { model = new User(0, "", "", ""); submitted = false; onSubmit() { console.log("PW" + this.model.password); } } 

没有看到你的源代码,很难看到这个问题。

重新加载您的网页和使用路由器之间的简化差异是:

  • 路由器将在标签内呈现路由。 这使您可以在页面内dynamic加载组件,而无需重新加载页面。
  • 重新加载你的页面会导致整个页面被重新加载,使用AoT编译的事件,这是非常昂贵的。 实际上不需要重新加载,所有的导航都应该在路由器中处理。

至于你的问题,它似乎是你多次加载该组件。 如果您正在讨论与工具提示重叠的文本,那么您可能是如何导入材料devise组件的依赖性问题。 发布你的代码,我会尽力帮助你。

所以,我假设你的问题是标签在重新加载之前被input重叠。 这与路由/重新加载无关(或者至less不是问题的根源)。 你的材料deviselite JS文件不是在做他的工作!

我在这里重新创build了这个问题并通过在这里添加lib 解决它。

这可能是由许多因素造成的:

  • MDL在组件被渲染后正在加载它的脚本。
  • 您的MDL.js已损坏/无法正常工作。
  • 你正在使用的第三部分库没有正确链接。

如果您使用的是angular-cli ,则需要将库添加到全局范围。 为此,请在.angular-cli.json文件中将path添加到lib中:

 ... "scripts": [ "/assets/js/material.min.js", ... ] ... 

Material Design Lite在dynamic渲染组件时需要一些额外的工作。 更多信息可以在他们的文档中find

TLDR; 在元素被注入到DOM之后,您需要调用componentHandler.upgradeElement。 下面的例子描述了我过去使用的方法。

编辑如果你想要一个声明性的解决scheme, 这里的方法看起来像一个相当不错的,但我没有使用它自己。

我创build了一个包装Material Lite componentHandler的服务

 import { Injectable } from '@angular/core'; export interface ComponentHandler { upgradeDom(); } declare var componentHandler: ComponentHandler; @Injectable() export class MaterialService { handler: ComponentHandler; constructor() { this.handler = componentHandler; } // render on next tick render() { setTimeout(() => { this.handler.upgradeDom(); }, 0); } } 

然后在组件向DOM中注入元素之后调用服务的render函数。

这是一个非常人为的例子,但是展示了“哪里”来调用渲染

 import { Component, OnInit } from '@angular/core'; import { DataService } from 'services/data.service'; import { MaterialService } from 'services/material.service'; @Component({ selector: 'app-thing', templateUrl: ` <ul> <li *ngFor="let item of data"> {{data}} </li> </ul> ` }) export class ThingComponent implements OnInit { data: string[] constructor( private service: DataService, private material: MaterialService ) { } ngOnInit() { this.service.getData() .subscribe(data => { this.data = data; this.material.render(); }); } }