Angular 从 angular 2 升级到 angular 4.4 时的路由器问题
Angular router issue when upgrading from angular 2 to angular 4.4
我按照 angular 官方 migrating_documentation 中提到的相同步骤进行操作。
不幸的是,我在将代码从 angular 2 迁移到 angular 4.4 时遇到了问题。该问题可能与@angular/router.
有关
然而,代码似乎工作正常,但我无法进行构建。任何建议将不胜感激。
Error shown in Terminal:
ERROR in [at-loader] src/app/app.component.ts:60:16
TS2339: Property 'url' does not exist on type 'Event'.
Property 'url' does not exist on type 'RouteConfigLoadStart'
ERROR in [at-loader] src/app/app.component.ts:60:39
TS2339: Property 'url' does not exist on type 'Event'.
Property 'url' does not exist on type 'RouteConfigLoadStart'.
ERROR in [at-loader] src/app/app.component.ts:60:68
TS2339: Property 'url' does not exist on type 'Event'.
Property 'url' does not exist on type 'RouteConfigLoadStart'.
Package.json
{
"name": "angular2-webpack",
"version": "1.0.0",
"description": "A webpack starter for Angular",
"scripts": {
"start": "webpack-dev-server --inline --progress --port 8080",
"test": "karma start",
"build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"
},
"license": "MIT",
"dependencies": {
"@angular/animations": "^4.4.7",
"@angular/common": "^4.4.7",
"@angular/compiler": "^4.4.7",
"@angular/compiler-cli": "^4.4.7",
"@angular/core": "^4.4.7",
"@angular/forms": "^4.4.7",
"@angular/http": "^4.4.7",
"@angular/platform-browser": "^4.4.7",
"@angular/platform-browser-dynamic": "^4.4.7",
"@angular/platform-server": "^4.4.7",
"@angular/router": "^4.4.7",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"dragula": "^3.7.2",
"fullcalendar": "^3.0.1",
"highcharts": "^5.0.9",
"jquery": "^3.1.1",
"jquery-mousewheel": "^3.1.13",
"jquery-ui": "^1.12.1",
"moment": "^2.17.1",
"ng2-dragula": "^1.3.0",
"primeng": "^2.0.2",
"rxjs": "5.0.1",
"webpack-strip": "^0.1.0",
"zone.js": "^0.7.4"
},
"devDependencies": {
"@types/google-maps": "^3.2.0",
"@types/jasmine": "2.5.36",
"@types/jquery": "^2.0.41",
"@types/node": "^6.0.45",
"angular2-template-loader": "^0.6.0",
"awesome-typescript-loader": "^3.0.4",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "2.0.0-beta.5",
"file-loader": "^0.9.0",
"html-loader": "^0.4.3",
"html-webpack-plugin": "^2.16.1",
"jasmine-core": "^2.4.1",
"karma": "^1.2.0",
"karma-chrome-launcher": "^2.0.0",
"karma-jasmine": "^1.0.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^2.0.1",
"null-loader": "^0.1.1",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.2",
"style-loader": "^0.13.1",
"typescript": "^2.3.4",
"url-loader": "^0.5.9",
"webpack": "2.2.1",
"webpack-bundle-size-analyzer": "^2.6.0",
"webpack-dev-server": "2.4.1",
"webpack-merge": "^3.0.0"
}
}
app.component.ts
import { Component,AfterContentInit,AfterViewInit,AfterViewChecked } from '@angular/core';
import { Location,PopStateEvent} from '@angular/common';
import * as myGlobals from './global_variable';
import { headerComponent } from './components/header/header.component';
import { footerComponent } from './components/footer/footer.component';
import { sidebarComponent } from './components/sidebar/sidebar.component';
import { mainPageComponent } from './components/main/mainpage.component';
import { Routes, RouterModule ,ActivatedRoute,Router,NavigationEnd,NavigationStart , ExtraOptions} from '@angular/router';
import {AuthService} from './services/auth.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html'
})
export class AppComponent {
public hideHeader:any = false;
public showHeader:any;
public showSidebarTrial:any = false;
public param_id:any;
headerTrialEmitter(e:any)
{
this.showSidebarTrial = e.value;
}
onActivate(e){
//alert(1.5);
}
onDeactivate(e)
{
// alert(1);
if(myGlobals.getCookie(window.location.pathname) == ''){
document.body.scrollTop = 0;
}else{
setTimeout(()=>{
// alert(2);
document.documentElement.scrollTop = Number(myGlobals.getCookie(window.location.pathname));
if(document.documentElement.scrollTop == 0){
document.body.scrollTop = Number(myGlobals.getCookie(window.location.pathname));
}
},2500);
}
}
constructor(private route:ActivatedRoute,private cons:RouterModule,public Location:Location,private router: Router,private AuthService:AuthService){
router.events.subscribe((val) => {
var patt = new RegExp("/reset-password/");
var found_rp = false;
if(patt.test(window.location.pathname))
{
found_rp = true;
}
if(val.url == '/login' || val.url == '/please-help' || val.url == '/reset-password' || found_rp){
this.hideHeader = false;
} else{
this.hideHeader = true;
}
});
this.router.events
.filter(e => e instanceof NavigationStart)
.pairwise().subscribe((e:any) => {
console.log(e,'pairwise');
// alert(window.location.pathname);
// alert(document.body.scrollTop);
if(e[0].url == '/login'){
}else if(e[0].url == e[1].url){
}else{
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
myGlobals.setCookie(e[0].url,scrollTop);
var cookies = document.cookie.split(";");
if(cookies.length > 2){
for(var i = 0;i < cookies.length;i++){
myGlobals.deleteCookie('')
}
}
}
});
if(window.location.pathname == "/login" || window.location.pathname == "/please-help"){
this.hideHeader = false;
// console.log("hideHeader1 true");
}else{
this.hideHeader = true;
}
}
}
当您订阅路由器事件时,将发出不同类型的事件:NavigationStart, RouteConfigLoadStart, RouteConfigLoadEnd, RoutesRecognized, GuardsCheckStart...
显然它们不具有所有相同的属性,属性 url
在 RouteConfigLoadStart 上不可用,但在 NavigationStart
或 NavigationEnd
上可用。
所以你可以做的是 filter
和 subscribe
像这样的事件类型:
this.router.events
.filter((event: any) => event instanceof NavigationEnd)
.subscribe((event: any) => {
// access event.url;
});
您已经在第二次订阅中这样做了,您过滤了 NavigationStart
。
从您的代码看来,您正试图在延迟加载期间访问 url。但是在 Angular 4+ 中 属性 url
不存在于 RouteConfigLoadStart
和 RouteConfigLoadEnd
类型的事件中。相反,您可以过滤事件以使用扩展 RouterEvent
class 并具有 url
属性 的 NavigationStart
事件。您可以像下面这样使用它 -
router.events.filter((e: Event) => e instanceof NavigationStart)
.subscribe((val:NavigationStart) => {
var patt = new RegExp("/reset-password/");
var found_rp = false;
if(patt.test(window.location.pathname))
{
found_rp = true;
}
if(val.url == '/login' || val.url == '/please-help' || val.url == '/reset-password' || found_rp){
this.hideHeader = false;
}
else
{
this.hideHeader = true;
}
});
这是一个类似的问题 - https://github.com/angular/angular/issues/14976
和路由器事件的文档
经过长时间搜索 google,我找到了 problem.Both 的解决方案上面提到的答案对于 angular 4 是正确的,但是,在 Angular 6 你需要使用下面提到的代码
Angular 6
导入下面提到的模块
import { filter,pairwise} from 'rxjs/operators'
并使用管道
this.router.events.pipe(
filter((val:Event) => val instanceof NavigationStart)).subscribe((val:any) => {
console.log(val,'check val function' , typeof val , val.url);
var patt = new RegExp("/reset-password/");
var found_rp = false;
if(patt.test(window.location.pathname))
{
found_rp = true;
}
if(val.url == '/login' || val.url == '/please-help' || val.url == '/reset-password' || found_rp){
this.hideHeader = false;
} else{
this.hideHeader = true;
}
});
我按照 angular 官方 migrating_documentation 中提到的相同步骤进行操作。
不幸的是,我在将代码从 angular 2 迁移到 angular 4.4 时遇到了问题。该问题可能与@angular/router.
有关然而,代码似乎工作正常,但我无法进行构建。任何建议将不胜感激。
Error shown in Terminal:
ERROR in [at-loader] src/app/app.component.ts:60:16
TS2339: Property 'url' does not exist on type 'Event'.
Property 'url' does not exist on type 'RouteConfigLoadStart'
ERROR in [at-loader] src/app/app.component.ts:60:39
TS2339: Property 'url' does not exist on type 'Event'.
Property 'url' does not exist on type 'RouteConfigLoadStart'.
ERROR in [at-loader] src/app/app.component.ts:60:68
TS2339: Property 'url' does not exist on type 'Event'.
Property 'url' does not exist on type 'RouteConfigLoadStart'.
Package.json
{
"name": "angular2-webpack",
"version": "1.0.0",
"description": "A webpack starter for Angular",
"scripts": {
"start": "webpack-dev-server --inline --progress --port 8080",
"test": "karma start",
"build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"
},
"license": "MIT",
"dependencies": {
"@angular/animations": "^4.4.7",
"@angular/common": "^4.4.7",
"@angular/compiler": "^4.4.7",
"@angular/compiler-cli": "^4.4.7",
"@angular/core": "^4.4.7",
"@angular/forms": "^4.4.7",
"@angular/http": "^4.4.7",
"@angular/platform-browser": "^4.4.7",
"@angular/platform-browser-dynamic": "^4.4.7",
"@angular/platform-server": "^4.4.7",
"@angular/router": "^4.4.7",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"dragula": "^3.7.2",
"fullcalendar": "^3.0.1",
"highcharts": "^5.0.9",
"jquery": "^3.1.1",
"jquery-mousewheel": "^3.1.13",
"jquery-ui": "^1.12.1",
"moment": "^2.17.1",
"ng2-dragula": "^1.3.0",
"primeng": "^2.0.2",
"rxjs": "5.0.1",
"webpack-strip": "^0.1.0",
"zone.js": "^0.7.4"
},
"devDependencies": {
"@types/google-maps": "^3.2.0",
"@types/jasmine": "2.5.36",
"@types/jquery": "^2.0.41",
"@types/node": "^6.0.45",
"angular2-template-loader": "^0.6.0",
"awesome-typescript-loader": "^3.0.4",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "2.0.0-beta.5",
"file-loader": "^0.9.0",
"html-loader": "^0.4.3",
"html-webpack-plugin": "^2.16.1",
"jasmine-core": "^2.4.1",
"karma": "^1.2.0",
"karma-chrome-launcher": "^2.0.0",
"karma-jasmine": "^1.0.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^2.0.1",
"null-loader": "^0.1.1",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.2",
"style-loader": "^0.13.1",
"typescript": "^2.3.4",
"url-loader": "^0.5.9",
"webpack": "2.2.1",
"webpack-bundle-size-analyzer": "^2.6.0",
"webpack-dev-server": "2.4.1",
"webpack-merge": "^3.0.0"
}
}
app.component.ts
import { Component,AfterContentInit,AfterViewInit,AfterViewChecked } from '@angular/core';
import { Location,PopStateEvent} from '@angular/common';
import * as myGlobals from './global_variable';
import { headerComponent } from './components/header/header.component';
import { footerComponent } from './components/footer/footer.component';
import { sidebarComponent } from './components/sidebar/sidebar.component';
import { mainPageComponent } from './components/main/mainpage.component';
import { Routes, RouterModule ,ActivatedRoute,Router,NavigationEnd,NavigationStart , ExtraOptions} from '@angular/router';
import {AuthService} from './services/auth.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html'
})
export class AppComponent {
public hideHeader:any = false;
public showHeader:any;
public showSidebarTrial:any = false;
public param_id:any;
headerTrialEmitter(e:any)
{
this.showSidebarTrial = e.value;
}
onActivate(e){
//alert(1.5);
}
onDeactivate(e)
{
// alert(1);
if(myGlobals.getCookie(window.location.pathname) == ''){
document.body.scrollTop = 0;
}else{
setTimeout(()=>{
// alert(2);
document.documentElement.scrollTop = Number(myGlobals.getCookie(window.location.pathname));
if(document.documentElement.scrollTop == 0){
document.body.scrollTop = Number(myGlobals.getCookie(window.location.pathname));
}
},2500);
}
}
constructor(private route:ActivatedRoute,private cons:RouterModule,public Location:Location,private router: Router,private AuthService:AuthService){
router.events.subscribe((val) => {
var patt = new RegExp("/reset-password/");
var found_rp = false;
if(patt.test(window.location.pathname))
{
found_rp = true;
}
if(val.url == '/login' || val.url == '/please-help' || val.url == '/reset-password' || found_rp){
this.hideHeader = false;
} else{
this.hideHeader = true;
}
});
this.router.events
.filter(e => e instanceof NavigationStart)
.pairwise().subscribe((e:any) => {
console.log(e,'pairwise');
// alert(window.location.pathname);
// alert(document.body.scrollTop);
if(e[0].url == '/login'){
}else if(e[0].url == e[1].url){
}else{
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
myGlobals.setCookie(e[0].url,scrollTop);
var cookies = document.cookie.split(";");
if(cookies.length > 2){
for(var i = 0;i < cookies.length;i++){
myGlobals.deleteCookie('')
}
}
}
});
if(window.location.pathname == "/login" || window.location.pathname == "/please-help"){
this.hideHeader = false;
// console.log("hideHeader1 true");
}else{
this.hideHeader = true;
}
}
}
当您订阅路由器事件时,将发出不同类型的事件:NavigationStart, RouteConfigLoadStart, RouteConfigLoadEnd, RoutesRecognized, GuardsCheckStart...
显然它们不具有所有相同的属性,属性 url
在 RouteConfigLoadStart 上不可用,但在 NavigationStart
或 NavigationEnd
上可用。
所以你可以做的是 filter
和 subscribe
像这样的事件类型:
this.router.events
.filter((event: any) => event instanceof NavigationEnd)
.subscribe((event: any) => {
// access event.url;
});
您已经在第二次订阅中这样做了,您过滤了 NavigationStart
。
从您的代码看来,您正试图在延迟加载期间访问 url。但是在 Angular 4+ 中 属性 url
不存在于 RouteConfigLoadStart
和 RouteConfigLoadEnd
类型的事件中。相反,您可以过滤事件以使用扩展 RouterEvent
class 并具有 url
属性 的 NavigationStart
事件。您可以像下面这样使用它 -
router.events.filter((e: Event) => e instanceof NavigationStart)
.subscribe((val:NavigationStart) => {
var patt = new RegExp("/reset-password/");
var found_rp = false;
if(patt.test(window.location.pathname))
{
found_rp = true;
}
if(val.url == '/login' || val.url == '/please-help' || val.url == '/reset-password' || found_rp){
this.hideHeader = false;
}
else
{
this.hideHeader = true;
}
});
这是一个类似的问题 - https://github.com/angular/angular/issues/14976 和路由器事件的文档
经过长时间搜索 google,我找到了 problem.Both 的解决方案上面提到的答案对于 angular 4 是正确的,但是,在 Angular 6 你需要使用下面提到的代码
Angular 6
导入下面提到的模块
import { filter,pairwise} from 'rxjs/operators'
并使用管道
this.router.events.pipe(
filter((val:Event) => val instanceof NavigationStart)).subscribe((val:any) => {
console.log(val,'check val function' , typeof val , val.url);
var patt = new RegExp("/reset-password/");
var found_rp = false;
if(patt.test(window.location.pathname))
{
found_rp = true;
}
if(val.url == '/login' || val.url == '/please-help' || val.url == '/reset-password' || found_rp){
this.hideHeader = false;
} else{
this.hideHeader = true;
}
});