我有一個大問題!
我有自定義指令,根據輸入入口放置隱藏屬性。
import { Directive, ElementRef, Input, OnInit, Renderer2 } from '@angular/core';
@Directive({
selector: '[ticketingPrimeCreateTicketButtonActive]'
})
export class CreateTicketButtonActiveDirective implements OnInit {
@Input() ticketingPrimeCreateTicketButtonActive: string;
constructor(private elRef: ElementRef, private renderer: Renderer2) {}
ngOnInit() {
console.log(this.ticketingPrimeCreateTicketButtonActive);
if (!(this.ticketingPrimeCreateTicketButtonActive === 'Administrador' || this.ticketingPrimeCreateTicketButtonActive === 'Comercial')) {
this.renderer.setAttribute(this.elRef.nativeElement, 'hidden', 'true');
}
}
}
該指令是否有效,因為當我對入口進行硬編碼時,它可以像這樣作業:
<button [ticketingPrimeCreateTicketButtonActive]="'Administrador'" [ngClass]="{ addInSmall: isSmallOrXSmall() }" (click)="addTicket()">
<span > add_to_photos </span>
</button>
那么問題是我必須從資料庫中取出那個字串。
我試圖創建一個 observable 并使用管道異步,但它總是為空。組件的非凡代碼:
export class TicketingKanbanComponent implements OnInit, OnDestroy, AfterViewInit {
public activeUserRoleNameSubject: BehaviorSubject<string>;
public activeUserRoleName$: Observable<string>;
....
}
async ngOnInit(): Promise<void> {
const roleUid = (await
this.userBaseGesRoleRepository.findOneByActiveUser().toPromise()).metadata.roleUid;
this.role = (await this.roleRespository.findOne(roleUid).toPromise()).metadata.name;
this.activeUserRoleNameSubject = new BehaviorSubject<string>(this.role)
this.activeUserRoleName$ = this.getActiveUserRoleName$();
....
}
private async getActiveUserRoleName() {
console.log(this.role);
this.activeUserRoleNameSubject.next(this.role);
}
private getActiveUserRoleName$(): Observable<string> {
return this.activeUserRoleNameSubject.asObservable();
}
當我像這樣傳遞引數時:
<button [ticketingPrimeCreateTicketButtonActive]="(this.activeUserRoleName$ | async )" [ngClass]="{ addInSmall: isSmallOrXSmall() }" (click)="addTicket()">
<span > add_to_photos </span>
</button>
該指令總是收到 null!
我知道如果必須成為生命周期的東西,但我已經嘗試了所有我認為應該有效的方法,它對我說不不不
編輯:
使用各種console.logs,我已經看到問題是它在ngoninit 從DDBB 獲取值之前拋出th 指令。
但我以前不知道怎么做。
編輯 2(固定):
我終于使它起作用,使 DDBB 在指令內部進行咨詢。
but i still dont if it should be possible resolve the consult of the database in the component before load the template, ecause in the constructor i cannot use async await.
uj5u.com熱心網友回復:
另一種解決方案是使用決議器來延遲您的組件。當它命中 ngOnInit 時,該值將已經從資料庫中獲取。看看Angular 決議器
uj5u.com熱心網友回復:
據我所知,您的問題顯然是組件和指令構建的生命周期。指令被創建并在當時從它的輸入ticketingPrimeCreateTicketButtonActive中獲取值,因為它是一個資料庫提取,很可能為空。它將繼續偵聽此值,但不會執行您想要并在 ngOnInit 中定義的行為,因為此生命周期事件僅發生一次。
我可以看到至少有 2 種可能的方法來解決這個問題。
第一的
您可以放棄使用自定義指令并依賴[hidden]="logicHere". 通過使用 Renderer 來操作 HTML 并不是很常見的做法。它看起來像這樣:
<button [hidden]="!((this.activeUserRoleName$ | async ) === 'Administrator' || (this.activeUserRoleName$ | async ) === 'Comercial')" [ngClass]="{ addInSmall: isSmallOrXSmall() }" (click)="addTicket()">
<span > add_to_photos </span>
</button>
或者只是用自定義函式替換隱藏內部的邏輯。
第二
您可以繼續使用自定義指令邏輯,但需要更改@Input管理方式。Angular 有一個很好的頁面解釋了這一點:https : //angular.io/guide/component-interaction
結果是這樣的:
import { Directive, ElementRef, Input, OnInit, Renderer2 } from '@angular/core';
@Directive({
selector: '[ticketingPrimeCreateTicketButtonActive]'
})
export class CreateTicketButtonActiveDirective implements OnInit {
@Input()
get ticketingPrimeCreateTicketButtonActive() {
return this._ticketingPrimeCreateTicketButtonActive;
};
set ticketingPrimeCreateTicketButtonActive(ticketingPrimeCreateTicketButtonActive: string){
this._ticketingPrimeCreateTicketButtonActive = ticketingPrimeCreateTicketButtonActive;
this.customFunction();
}
private _ticketingPrimeCreateTicketButtonActive = '';
constructor(private elRef: ElementRef, private renderer: Renderer2) {}
customFunction() {
if (!(this._ticketingPrimeCreateTicketButtonActive === 'Administrador' || this._ticketingPrimeCreateTicketButtonActive === 'Comercial')) {
this.renderer.setAttribute(this.elRef.nativeElement, 'hidden', 'true');
} else {
this.renderer.setAttribute(this.elRef.nativeElement, 'hidden', 'false');
}
}
}
在這里,customFunction每次呼叫的價值@Input變化。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/322426.html
標籤:angular asynchronous pipe directive
