- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在加载我的 Angular 2 应用程序之前,我试图从数据库中获取一些配置选项。 Angular 应用程序在启动之前需要等待数据加载,因为应该根据这些配置选项限制对某些组件的访问。
所以我创建了一个 ConfigurationService 来从后端获取数据,并且我试图在启动应用程序之前使用根模块中的 app_initializer 来调用配置服务。我已经设法在我几个月前创建的 Angular 应用程序( Angular RC4)中做到了这一点,并且这次一开始尝试以同样的方式做到这一点。
app.module.ts - 第一次尝试
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { AppComponent } from './app.component';
import { RouterModule } from '@angular/router';
import { HttpModule } from '@angular/http';
import { ConfigurationService } from "./shared/services/configuration.service";
@NgModule({
imports: [
...
],
declarations: [
...
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: (config: ConfigurationService) => () => config.loadConfiguration(),
deps: [ConfigurationService]
},
ConfigurationService
],
bootstrap: [AppComponent]
})
export class AppModule { }
这导致了以下错误:
Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function
我认为这与我正在使用的 AoT 编译器有关。我用工厂替换了 lambda 表达式。
app.module.ts - 第二次尝试
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { AppComponent } from './app.component';
import { RouterModule } from '@angular/router';
import { HttpModule } from '@angular/http';
import { ConfigurationService } from "./shared/services/configuration.service";
import { ConfigurationServiceFactory } from "./shared/services/configuration.service.factory";
@NgModule({
imports: [
...
],
declarations: [
...
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: ConfigurationServiceFactory,
deps: [ConfigurationService]
},
ConfigurationService
],
bootstrap: [AppComponent]
})
export class AppModule { }
configuration.service.factory.ts
import { ConfigurationService } from "./configuration.service";
export function ConfigurationServiceFactory(configurationService: ConfigurationService) {
return configurationService.loadConfiguration()
.then(currentUser => {
configurationService.currentUser = currentUser;
}
);
}
这实际上使用配置服务从后端获取数据,但不会在启动应用程序之前等待 promise 解决。当用户从主页(每个人都可以访问)开始,然后导航到一个仅限于非管理员用户的组件时,它就会起作用。但是当用户刷新受限制的页面时,OnInit(我确定用户是否具有访问权限)在加载配置之前触发。在我的例子中,这会导致用户被拒绝访问他们应该有权访问的页面。
configuration.service.ts
import { Injectable } from "@angular/core";
import { Http, Response } from '@angular/http';
import { CurrentUser } from "../models/currentuser.model";
@Injectable()
export class ConfigurationService {
public apiUrl: string = "api/";
public currentUser: CurrentUser;
constructor(private http:Http) {}
/**
* Get configuration from database
*/
public loadConfiguration(): Promise<CurrentUser> {
return this.http.get(this.apiUrl + "application/GetDataForCurrentUser")
.toPromise()
.then(this.extractData)
.catch(this.handleError);
}
}
组件实现
import { Component, OnInit } from '@angular/core';
import { MessageService } from '../shared/message/message.service'
import { ConfigurationService } from "../shared/services/configuration.service";
@Component({
selector: 'simple',
templateUrl: 'simple.component.html'
})
export class SimpleComponent implements OnInit{
constructor(private messageService: MessageService, private configurationService: ConfigurationService) {
}
ngOnInit() {
if (!this.configurationService.isAdmin()) {
this.messageService.addMessage("Access denied", "danger");
}
}
}
此时我完全没有想法,我一直在寻找解决方案,但只设法找到推荐 lambda 选项的人,这对我不起作用。
最佳答案
在@DzmitryShylovich 的帮助下 angular gitter channel ,谁指出从 app.module.ts 内部调用服务已经晚了,我应该从 main.ts 文件中调用服务,我设法解决了我的问题。他向我提供了以下 plnkr .
这就是我在自己的解决方案中为使其正常工作所做的工作。
常量.ts
import { OpaqueToken } from '@angular/core'
export const CONFIG_TOKEN = new OpaqueToken('config');
我创建了一个 OpaqueToken to avoid naming collisions
main.ts
import { platformBrowser } from '@angular/platform-browser';
import { AppModuleNgFactory } from '../aot/app/app.module.ngfactory';
import { CONFIG_TOKEN } from './shared/constants/constants'
const configApi = "yoururlhere";
fetch(configApi, {
credentials: 'include'
}).then(parseResponse);
function parseResponse(res: any) {
return res.json().then(parseData);
}
function parseData(data: any) {
return platformBrowser([{ provide: CONFIG_TOKEN, useValue: data }]).bootstrapModuleFactory(AppModuleNgFactory);
}
在我的 main.ts 文件中,我调用网络服务来获取我的配置数据、解析数据并创建一个提供程序以传递到我的应用程序中。我将凭据设置为包含,因为我在 Web 服务上使用 Windows 身份验证,当您没有明确告诉提取提供凭据时,它会给出 401。
app.component.ts
import { Component, OnInit, Inject } from "@angular/core";
import { CONFIG_TOKEN } from './shared/constants/constants'
@Component({
selector: "app",
templateUrl: "app.component.html"
})
export class AppComponent implements OnInit {
public configuration: any;
public isAdmin: boolean;
constructor(@Inject(CONFIG_TOKEN) config: any) {
this.configuration = config;
}
ngOnInit() {
this.isAdmin = this.configuration.currentUser_IsAdmin;
}
}
在我的 app.component 中,我可以注入(inject)我创建的提供者以使用我从 web 服务获得的配置对象。
typescript 问题
我在开发这个解决方案时遇到了 visual studio 中的 typescript 问题,我得到了以下错误:
error TS2304: Cannot find name 'fetch'.
我通过手动下载 whatwg-fetch typescript 定义文件解决了这个问题
npm install --save-dev @types/whatwg-fetch
@DzmitryShylovich,感谢您的帮助!
关于angular - 在 Angular 2 应用程序开始使用 AoT 之前从数据库加载配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41035581/
我正在尝试从 Unity 发布到我的 iPhone 4s。构建成功,但我继续收到此消息: “在 aot-only 模式下运行时无法加载 AOT 模块‘Assembly-CSharp’,因为依赖项无法找
在听说了这么多有关 Angular AOT 模式的信息后,我想尝试一下。因此,我们将应用程序迁移到 Angular v4.1.2,并进行了所有必要的更改。当我尝试使用我的 webpack 配置文件中的
我有一个 C# 项目,我需要将其编译为 native 二进制文件。我在这里读过: http://www.mono-project.com/AOT Mono 可以将程序集预编译为两个选项之一: --ao
我搜索了很多关于这种伟大语言的信息,并在此页面上找到了自己 https://github.com/dart-lang/sdk/wiki/Snapshots但它没有回答一些问题: 快照和 AOT 有什么
我知道什么是字节码检测。它只是在运行时更改 .class 文件字节码,这似乎从 JDK 1.5 开始可用。但是,据说是在类加载期间而不是运行时。 现在我的问题是,什么是 AOT 或提前检测?相反的程序
我正在为我的应用程序构建一个插件系统。我读到任何人都可以反编译 .class 文件,因此我不得不使用 Ahead-Of-Time 编译器(对吗?)。问题是我需要动态加载一些插件类。现在,我正在将所有
我的问题是 Angular 模块之一无法在 Safari 浏览器中正常工作。 我有以下代码: @NgModule({ bootstrap: [ AppComponent ], impo
我在这里问是因为我无法在网上找到完整的文档。示例 here太简单了。我有一个包含多个组件和一些模块的应用程序。用ngc编译后,我有很多错误。我发现修复它们的方法是使用相对路径。因此,我在所有组件中都使
在使用 webpack 进行 AOT 构建后,bundle 将每个组件模板包含两次,使得 bundle 比需要的大得多,因为模板作为字符串包含在内,UglifyJS 无法缩小。 我希望组件模板被排除为
我正在尝试使用 ngc 编译 angular 2.4.4: Error: Error encountered resolving symbol values statically. Expressio
当我这样做时,有什么原因(我可以解决): ngc -p tsconfig.aot.json 作为回应,它要求: 姓名: ngc 似乎忽略了我的 tsconfig.aot.json。 这可能是什么原因?
我正在开发一个 Angular 7 应用程序,除了加载问题外它工作正常,在研究中我发现我应该使用 AOT 构建而不是 JIT 或正常构建,由于应用程序规模巨大,我无法进行 aot 构建,它正在返回堆我
我在 Dynamics AX 2012 中有一个 AOT 查询,它由 HcmWorker 和 HcmEmployment 表(等等)组成。我的问题是,当我创建报告(不是 SSRS)或以其他方式使用此查
有谁知道在使用带有 AOT 编译的 Angular CLI 时如何获得更详细的错误堆栈跟踪?使用 JIT 编译运行时,我的应用程序没有问题,但是当我运行 ng build --aot 时,我得到的只是
我想查询 AOT 以查看是否存在使用 X++ 的表名。谁能指出我正确的方向或提供一些示例代码来做到这一点? 如果表存在并提供名称 (str tableName),则返回 true;否则,返回false
我有一个 Angular 5 应用程序,当我在测试模式下运行时没有问题,也就是说,当我使用 ng serve 命令在本地运行应用程序时。但是,当我在生产模式下部署应用程序时,即通过命令ng build
语境 我正在创建一个 Angular 应用程序的桌面版本,为此我正在使用 Electron 。 打开主窗口非常简单: win = new BrowserWindow({ width: 1280
我有一个看起来像这样的错误处理程序: @Injectable() export class GlobalErrorHandler implements ErrorHandler { construct
当我尝试构建启用了 AOT 选项的 Android 应用程序时,收到以下错误消息。 Invalid command line switch for "aapt.exe". VersionCode is
我在我的 Angular 2 应用程序中使用 Highcharts 和 Kendo Charts,当我尝试运行 AOT 编译时,它会抛出类似的错误 Cannot Import Module 或 Hom
我是一名优秀的程序员,十分优秀!