Angular 4.X 踩坑集錦

JerryMissTom發表於2017-07-03

GitHub地址:github.com/JerryMissTo… ,歡迎關注

使用ngIf或者ngSwitch出錯

在html檔案中使用ngIf或者ngSwitch時,會解析出錯,錯誤提示如下:

Error: Template parse errors:
Can't bind to 'ngSwitch' since it isn't a known property of 'div'.複製程式碼

這個是因為沒有在此Component所在的Module中匯入CommonModule,雖然你可能在AppModule中匯入過了,但是還是需要匯入一次,程式碼如下:

import { CommonModule } from '@angular/common';
@NgModule(
    {
        declarations: [ ],
        imports: [
            CommonModule
        ],
        exports: [ ],
        providers: [ ]
    }
)
export class MainModule { }複製程式碼

多級依賴注入器

Angular 4.X擁有多級依賴注入系統,在一個注入器的範圍內,依賴都是單例的。它使用冒泡機制,當一個元件申請獲得一個依賴時,Angular 先嚐試用該元件自己的注入器來滿足它。 如果該元件的注入器沒有找到對應的提供商,它就把這個申請轉給它父元件的注入器來處理。 如果那個注入器也無法滿足這個申請,它就繼續轉給它的父元件的注入器。

舉個例子,從登入頁點選登入按鈕進入主頁,LoginComponentMainComponent都注入了LoginService

登入:

//login.service.ts
// 這個是登入服務
import { Injectable } from '@angular/core';

@Injectable()
export class LoginService {
    isLoggedIn: boolean = false;
    login(){
        this.isLoggedIn=true;
    }
}複製程式碼
// login.component.ts
//登入介面,只有一個登入按鈕,點選後登入會把LoginService中的isLoggedIn變為true

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { LoginService } from '../login/login.service';
@Component({
  selector: 'app-login',
  template:`<button (click)=login()>Login </button>`,
  providers: [LoginService]
})
export class LoginComponent implements OnInit {

  constructor(private router: Router, private loginService: LoginService) { }

  login() {
    this.loginService.login();
    console.log(this.loginService.isLoggedIn); //結果為true
    this.router.navigate(['/main']);
  }
}複製程式碼
// main.component.ts
// 這個是登陸後的主介面

import { Component} from '@angular/core';
import { LoginService } from '../login/login.service';

@Component({
  selector: 'app-main',
  template: `<h1>HOME</h1>`,
  providers: [LoginService]
})
export class MainComponent implements OnInit {

  private userType: string ;
  constructor(private loginService: LoginService) {
    console.log(this.loginService.isLoginIn); //結果為false
  }
}複製程式碼

從上面的例子可以看出來,在不同的地方注入同樣的Service,但是會使用不同的例項,所以會導致結果可能不同,需要注意。

pipe使用報錯,出現cross module問題

app.module.ts中的declarations引入後,在子模組的 *.component.ts中使用會報錯。把pipe在子模組中宣告使用即可。

不同資料夾下Module同名導致webpack打包失敗

假如兩個資料夾下分別有FristModuleSecondModule兩個模組,他們都有名為HomeModule的子模組,webpack打包的時候會出錯,log為:ERROR in Duplicated path in loadChildren detected ......Webpack cannot distinguish on context and would fail to load the proper one.。可以在FirstModulerouter中通過絕對路徑的形式來規避此問題。例子程式碼如下:

export const firstRoutes = [{
    path: '',
    children: [
        {path: '', redirectTo: 'home', pathMatch: 'full'},
        {path: 'home', loadChildren: 'app/first/home/home.module#HomeModule'},
        {path: '**', redirectTo: 'home'}
    ]
}];複製程式碼
export const secondRoutes = [{
    path: '',
    children: [
        {path: '', redirectTo: 'home', pathMatch: 'full'},
        {path: 'home', loadChildren: 'app/second/home/home.module#HomeModule'},
        {path: '**', redirectTo: 'home'}
    ]
}];複製程式碼

設定全域性的CSS樣式

我們通常會有自己的CSS樣式庫來保證視覺效果的統一,可以把css樣式寫在app資料夾下的styles.css中,確保.angular-cli.json"styles": [ "styles.css"]保持對應,然後在*.component.html的控制元件中直接使用,無需在index.html中通過<link>標籤引入,也無需其他的任何操作。

cannot find *.module的可能情況

1、router中loadChildren中的路徑不對
2、router中寫入某componenet的路徑,但是沒有在對應的Module的declarations中宣告

打包報錯:Supplied parameters do not match any signature of call target

這個是由於寫程式碼不嚴謹造成的,具體可參考:blog.csdn.net/crper/artic…

ng build部署後base檔案路徑問題

通過ng build --prod打包之後,會停留在loading,log提示找不到css,js等檔案,這個是由index.html中base路徑設定引起的,修改為相對路徑就可以:< base href="./">

重新整理出現404錯誤

這個是與Angular的 重新整理策略相關,在app.module設定如下:

import { HashLocationStrategy, LocationStrategy } from '@angular/common';
providers: [
        LoginService,
        { provide: LocationStrategy, useClass: HashLocationStrategy }
    ],複製程式碼

相關文章