#angular #angular-router-guards
#угловатый #angular-router-guards
Вопрос:
У меня есть библиотека Angular 10, в которой есть защита. Я хочу экспортировать защиту для использования на маршрутизаторе приложения-потребителя. Я пошел по пути экспорта защиты в my public-api.ts
, но я получаю ошибку сборки, Document
тип которой не может быть разрешен. Я внедряю DOCUMENT
в свою защиту. Ошибка и код защиты ниже. Есть какие-либо рекомендации по экспорту?
Ошибка сборки:
Metadata collected contains an error that will be reported at runtime: Could not resolve type Document.
{"__symbolic":"error","message":"Could not resolve type","line":19,"character":40,"context":{"typeName":"Document"}}
Защита:
import { Inject, Injectable, OnDestroy } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { Router, CanActivate } from '@angular/router';
import { Subscription } from 'rxjs';
import { QrRedirectService } from './qr-redirect.service';
import { MobileOS, QrUser } from '../qr-lib.model';
import { QR_LIB_CONFIG } from '../qr-lib.config.token';
import { QrLibConfig } from '../qr-lib.config';
@Injectable()
export class QrRedirectGuard implements CanActivate, OnDestroy {
config: QrLibConfig;
qrUser: QrUser;
redirectUrl: string;
redirectSubscription: Subscription;
constructor(
@Inject(QR_LIB_CONFIG) qrLibConfig,
@Inject(DOCUMENT) private document: Document,
public qrRedirectService: QrRedirectService,
public router: Router,
) {
if (qrLibConfig) {
this.config = qrLibConfig;
}
(this.redirectSubscription = this.qrRedirectService
.getQrUser()
.subscribe((user: QrUser) => {
this.qrUser = user;
})),
// tslint:disable-next-line: no-unused-expression
(error: any) => {
console.error(error);
};
}
ngOnDestroy(): void {
this.redirectSubscription.unsubscribe();
}
/**
* The `Window` object from `Document` defaultView.
*/
get window(): Window {
return this.document.defaultView || window;
}
/**
* Redirects instantly to the external link without the mediation of the router.
*/
public redirect(url: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
try {
resolve(!!this.window.open(url));
} catch (e) {
reject(e);
}
});
}
/**
* Returns `true` if user is on Android device.
*/
isAndroid(osName: string): boolean {
return osName === MobileOS.Android;
}
/**
* Returns `true` if user is on iOS device.
*/
isIOS(osName: string): boolean {
return osName === MobileOS.iOS;
}
/**
* Returns `false` if `QrUser` and `os` are valid, redirects to app store,
* and directs the router to stop navigation.
* Returns `true` if `QrUser` or `os` is invalid which directs the router
* to continue with navigation.
*/
canActivate(): boolean {
if (this.qrUser amp;amp; this.qrUser.os) {
if (this.isAndroid(this.qrUser.os)) {
this.redirectUrl = this.config.androidStoreUrl;
}
if (this.isIOS(this.qrUser.os)) {
this.redirectUrl = this.config.iosStoreUrl;
}
if (this.redirectUrl) {
// Jumps to the external url
this.redirect(this.redirectUrl).then(() => false);
}
}
// default route (qr landing page)
return true;
}
}
Ответ №1:
Изменение @Inject(DOCUMENT) private document: Document
на @Inject(DOCUMENT) private document: any
должно позволить вашей библиотеке создавать.
Комментарии:
1. Испытал то же самое 2 недели назад. Основываясь на этом, вы все равно можете удалить
private
ключевое слово из параметра injection (@Inject(DOCUMENT) document: any
) , добавитьprivate document: Document;
поле в свой класс и выполнить присваивание в конструкторе (this.document = <Document>document;
) . Таким образом, вам не нужно выполнять приведение каждый раз, когда вы хотите использоватьdocument
. До тех пор, пока параметр injection имеет типany
.