angular6.x--其它

EventEmitter實(shí)現(xiàn)自定義事件

通常,指令使用 Angular EventEmitter 來觸發(fā)自定義事件。 指令創(chuàng)建一個(gè)EventEmitter實(shí)例,并且把它作為屬性暴露出來。 指令調(diào)用EventEmitter.emit(payload)來觸發(fā)事件

deleteRequest = new [EventEmitter](https://angular.cn/api/core/EventEmitter)<Hero>(); 
delete() { 
this.deleteRequest.emit(this.hero); 
}

模板表達(dá)式操作符

管道操作符 ( | )
<div>Title through uppercase pipe: {{title | uppercase}}</div>

安全導(dǎo)航操作符 ( ?. ) 和空屬性路徑

Angular 的安全導(dǎo)航操作符 (?.) 是一種流暢而便利的方式,用來保護(hù)出現(xiàn)在屬性路徑中 null 和 undefined 值。 下例中,當(dāng)currentHero為空時(shí),保護(hù)視圖渲染器,讓它免于失敗。
<span>{{currentClasses?.colorC}}</span>

加上安全操作符 ?. 后,如果currentClasses對(duì)象沒有colorC屬性時(shí),span標(biāo)簽里沒有內(nèi)容,也不會(huì)報(bào)錯(cuò)。

常見問題

1.date

'Missing locale data for the locale "fr".' for pipe 'DatePipe'

import{ registerLocaleData} from '@angular/common';

import localeFr from '@angular/common/locales/fr';

registerLocaleData(localeFr, 'fr');

[<u>https://angular.cn/guide/i18n</u>](https://angular.cn/guide/i18n)

2. post請(qǐng)求請(qǐng)求頭報(bào)錯(cuò)

Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers

  private headers= new Headers({'Content-Type': 'application/json'});

對(duì)于跨域請(qǐng)求,將內(nèi)容類型設(shè)置為應(yīng)用程序/x-www-form- urlencoding、multipart/form-data或text/plain之外的任何內(nèi)容類型,都會(huì)觸發(fā)瀏覽器向服務(wù)器發(fā)送飛行前選項(xiàng)請(qǐng)求。

因此,盡管服務(wù)器允許跨源請(qǐng)求,但不允許訪問控制允許頭文件,它將拋出錯(cuò)誤。默認(rèn)情況下,angular的內(nèi)容類型是application/json,它試圖發(fā)送一個(gè)選項(xiàng)請(qǐng)求。嘗試在服務(wù)器端覆蓋angular默認(rèn)的標(biāo)頭或允許訪問控制允許標(biāo)頭。下面是一個(gè)angular示例:

private headers= new Headers({'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'});
  1. ngFor報(bào)錯(cuò)
    Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays
this.myStock= this.quoSer.loadStockBaseMsg(list, 1, 'zd,zdf')

.subscribe(res => {

console.log(res);

this.myStock= res;

});

去掉 this.nyStock =就可以了

this.quoSer.loadStockBaseMsg(list, 1, 'zd,zdf')

.subscribe(res => {

console.log(res);

this.myStock= res;

});
  1. 運(yùn)行項(xiàng)目不能自動(dòng)打開瀏覽器

運(yùn)行命令:ng serve --open即可

  1. 新建項(xiàng)目報(bào)錯(cuò)
    Schematic input does not validate against the Schema: {"name":"angular_ng","version":"6.1.3","newProjectRoot":"projects","skipInstall":false,"linkCli":false,"skipGit":false,"commit":null} Errors:Data path ".name" should match format "html-selector".

項(xiàng)目名稱格式不對(duì),改一下項(xiàng)目名稱就解決了。

6.語言切換主菜單不改變問題

app.component.html

在引用的地方加上打開關(guān)閉主菜單的監(jiān)聽函數(shù)(ionWillOpen)="menuOpen()" (ionDidClose)="menuClose()"

<ion-menu type="push" (ionWillOpen)="menuOpen()" (ionDidClose)="menuClose()">

<ion-header>

<ion-toolbar>

<ion-title i18n="菜單|app">菜單</ion-title>

</ion-toolbar>

</ion-header>

<ion-content>

<app-main-menu [itemActive]="currLoc" [menuStatus]="isOpen"></app-main-menu>

</ion-content>

</ion-menu>

menuOpen() {

this.isOpen= true;

}

menuClose() {

this.isOpen= false;

}

打開菜單,關(guān)閉菜單時(shí)改變變量isOpen,用來標(biāo)記當(dāng)前菜單狀態(tài);

把變量isOpen傳遞給主菜單組件

<app-main-menu [menuStatus]="isOpen"></app-main-menu>

在子組件接收菜單狀態(tài)

@Input()

set menuStatus(val:boolean) {

this.isOpen= val;

if(val) {

this.translate.setDefaultLang(this.setting.getSettings().lang);

}

}

get menuStatus() {return this.isOpen;}

當(dāng)收到菜單為打開時(shí),就去設(shè)置語言,這樣就解決了。

image.png

7.頁面銷毀事件不執(zhí)行問題
html跳轉(zhuǎn)的路由‘routerDirection’賦值為‘root’可以解決;
[routerDirection]="'root'"

js跳轉(zhuǎn):

import{ AlertController, ToastController, ModalController, NavController} from '@ionic/angular';

nav: NavController

this.nav.navigateRoot('/users/firstSet');

測(cè)試報(bào)錯(cuò)

1. location

angular NullInjectorError: No provider for Location

報(bào)著個(gè)錯(cuò)是因?yàn)閟pec.ts文件里沒有導(dǎo)入Location,需要導(dǎo)入:

import {Location } from '@angular/common';

providers注入

providers: [

Location,

...

]

之后在測(cè)試,如果又出現(xiàn)新的報(bào)錯(cuò) angular NullInjectorError: No provider for LocationStrategy

則需要繼續(xù)導(dǎo)入LocationStrategy:

import {Location ,LocationStrategy} from '@angular/common';

providers注入

providers: [

Location,

{ provide: LocationStrategy, useClass:PathLocationStrategy },

...

]

繼續(xù)運(yùn)行測(cè)試可能還會(huì)出現(xiàn)以下報(bào)錯(cuò)
TypeError: this._platformStrategy.getBaseHref is not a function

還需繼續(xù)導(dǎo)入PathLocationStrategy, APP_BASE_HREF

import {Location ,LocationStrategy, PathLocationStrategy, APP_BASE_HREF} from '@angular/common';

providers: [

Location,

{ provide: LocationStrategy, useClass:PathLocationStrategy },

{ provide: APP_BASE_HREF, useValue: '/my/app'}

...

]

2. NavParams

報(bào)錯(cuò): Can't resolve all parameters for NavParams: (?) (ionic)

解決:

在測(cè)試文件里添加

providers: [

{ provide: NavParams, useClass: class{ NavParams= jasmine.createSpy('NavParams'); }},

{ provide: NavParams, useValue:{ data:{ 'MYVALUE': 'XYZ'}}}

]

3. post\get請(qǐng)求JSON報(bào)錯(cuò)問題
Unexpected end of JSON input in ...

this.http.post(loc, JSON.stringify(pm), {headers: this.headers}).pipe(

map(res => {

res.json();

})

)

.subscribe(res => {

this.quotesContext.session= res.data.session;

}, err => {

console.error('登錄jybData失敗:', err);

});

如果res為空/未定義/空字符串,您將得到錯(cuò)誤。在使用res.json()之前,只需檢查res的值,就不會(huì)得到錯(cuò)誤。為了確保這一點(diǎn),在嘗試解析它之前先創(chuàng)建一個(gè)console.log(res)。

參照如下修改就不會(huì)報(bào)錯(cuò):

map(res => {

if (res) {

return res.json();

}

})

4. 表單報(bào)錯(cuò)

1.No value accessor for form control with name: 'name'

<ion-range [(ngModel)]="buyFund" (ionBlur)="fundSelected()" pin="true" min="0" [max]="maxbuy" name="name" [ngModelOptions]="{standalone: true}" color="danger"></ion-range>

只需要添加上ngDefaultControl屬性即可

<ion-range [(ngModel)]="buyFund" (ionBlur)="fundSelected()" pin="true" min="0" [max]="maxbuy" name="name" [ngModelOptions]="{standalone: true}" color="danger" ngDefaultControl></ion-range>

2.Can't bind to 'formGroup' since it isn't a known property of 'form'.

在使用form表單時(shí),如果用到了form-group與formControlName,需要在app.module.ts中的import引入的不僅僅有FormsModule,還要引入ReactiveFormsModule。

import { ReactiveFormsModule, FormsModule } from '@angular/forms';

@NgModule({

    imports: [

        FormsModule,

        ReactiveFormsModule

           ]

})

5. platform

this.platform.is is not a function

測(cè)試文件:

import{ Platform, AlertController, ToastController} from '@ionic/angular';

beforeEach(async() => {

platformReadySpy= Promise.resolve();

platformSpy= jasmine.createSpyObj('Platform', { ready: platformReadySpy,is:()=> {} });

TestBed.configureTestingModule({

providers: [

{ provide: Platform, useValue: platformSpy },

],

}).compileComponents();

});

6.The pipe 'translate' could not be found

import{ TranslateModule} from '@ngx-translate/core';

imports: [TranslateModule.forRoot()]

7.ERROR in node_modules/@biesbjerg/ngx-translate-extract/dist/cli/cli.d.ts(1,23): error TS2688: Cannot find type definition file for 'yargs'

多語言翻譯文件引用地址錯(cuò)誤

import{ _} from '@biesbjerg/ngx-translate-extract';

改為一下引用地址即可:

import{ _} from '@biesbjerg/ngx-translate-extract/dist/utils/utils';

8. ERROR Error: ExpressionChangedAfterItHasBeenCheckedError:

Expression has changed after it was checked. Previous value: 'model: undefined'. Current value: 'model: false'.

原因:Angular通過修補(bǔ)一些異步api(如addEventHandler、setTimeout等)來知道事件何時(shí)被完全處理,然后在每個(gè)事件之后運(yùn)行變更檢測(cè)。

在開發(fā)模式下,Angular會(huì)在第一個(gè)變更檢測(cè)之后執(zhí)行一個(gè)額外的變更檢測(cè)。因?yàn)橹虚g沒有事件,所以不應(yīng)該發(fā)生任何變化。如果模型仍然改變,Angular認(rèn)為這是一個(gè)可能的bug。

在開發(fā)模式中,更改檢測(cè)將第二次運(yùn)行,并將當(dāng)前值與第一次運(yùn)行進(jìn)行比較。 如果值不同,那么它“認(rèn)為”更改是由它自己引起的。這就是它拋出的原因。但是,在enableProdMode()的生產(chǎn)模式中不會(huì)發(fā)生這種情況。

解決方法:

在main.ts里添加

import {  enableProdMode } from  '@angular/core';

enableProdMode();
  1. cookie

儲(chǔ)存cookie

this.cookieService.set("userId",this.userId,new Date(new Date().getTime() + this.time));

this.cookieService.set("userName",response.data.name,new Date(new Date().getTime() + this.time));

讀取cookie

this.cookieService.get("userId");

this.cookieService.get("userName");

重新存儲(chǔ)cookie

this.cookieService.set("userId",this.cookieService.get("userId"),new Date(new Date().getTime() + this.time));

this.cookieService.set("userName",this.cookieService.get("userName"),new Date(new Date().getTime() + this.time));

刪除cookie

this.cookieService.delete("userId");

check( name: string ): boolean;
get( name: string ): string;
set( name: string, value: string, expires?: number | Date, path?: string, domain?: string, secure?: boolean, sameSite?: 'Lax' | 'Strict' ): void;
delete( name: string, path?: string, domain?: string ): void;
deleteAll( path?: string, domain?: string ): void;

8.共享模塊
項(xiàng)目中分有多個(gè)模塊(Module),當(dāng)兩個(gè)或多個(gè)模塊都引用同一個(gè)服務(wù)、管道等組件時(shí),angular編譯會(huì)報(bào)錯(cuò),這種情況需要新創(chuàng)建一個(gè)共享模塊,來承載共用組件;

image.png

image.png

如上圖所示,項(xiàng)目quotes模塊和trade模塊都引入了xpipes.ts里的adata管道,如果在quotes.Moudle和tradeModule里直接引用AdataPipe就會(huì)報(bào)錯(cuò),所以新建一個(gè)共享模塊(ng g module share),在share.module.ts里引入共用的管道

share.module.ts:

import{ NgModule} from '@angular/core';

import{ CommonModule} from '@angular/common';

import {  AdataPipe, LimitToPipe} from '../components/pipes/xpipes';

@NgModule({

imports: [

CommonModule

],

declarations: [

AdataPipe,

LimitToPipe

],

exports: [

AdataPipe,

LimitToPipe

]

})

export class ShareModule { }

然后再把shareModule引入到兩個(gè)用到管道的模塊里:

image.png

image.png

這樣就可以在quotes.Moudle和tradeModule這兩個(gè)模塊下的組件里用shareModule導(dǎo)出的管道了;(這里舉例是管道,服務(wù)等其他共用都參照這種做法);

9.移動(dòng)端點(diǎn)擊事件監(jiān)聽
(touchstart)="addColor()" (touchend)="removeColor()"
相當(dāng)于電腦網(wǎng)頁的keydown、keyup事件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容