从Razor视图迁移至Angular 4:非Ajax传递服务端全局常量
嘿,我刚好踩过这个从Razor转Angular 4的迁移坑,给你几个不用Ajax就能从ASP.NET MVC后端把全局常量传给Angular的实用法子,亲测靠谱:
这是最直接的方式,利用Razor的渲染能力,在页面加载时就把后端常量塞到全局对象里,Angular直接就能取到。
步骤很简单:
- 在你的主Razor视图(比如_Layout.cshtml或者Angular入口的Index.cshtml)里,在Angular脚本加载之前,添加这段代码:
<script> // 用一个专门的全局对象存常量,避免污染全局空间 window.appGlobalConstants = { transactionStatuses: @Html.Raw(Json.Serialize(Model.TransactionStatuses)), // 其他需要的常量都可以加在这,比如系统配置、枚举值之类的 }; </script>
这里的Model.TransactionStatuses就是你从数据库查出来的交易状态列表,用Json.Serialize转成JSON字符串,再用Html.Raw确保渲染成合法的JS对象。
- 在Angular里创建一个服务来封装这些常量,别直接用window(避免耦合):
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' // 全局单例服务 }) export class GlobalConstantsService { // 封装交易状态的 getter get transactionStatuses() { return (window as any).appGlobalConstants.transactionStatuses; } // 其他常量的 getter 同理 }
之后在任何组件里,只要注入这个服务就能用常量了:
import { Component } from '@angular/core'; import { GlobalConstantsService } from './global-constants.service'; @Component({ selector: 'app-transaction-list', templateUrl: './transaction-list.component.html' }) export class TransactionListComponent { constructor(private constantsService: GlobalConstantsService) { // 直接用常量 console.log(this.constantsService.transactionStatuses); } }
优点:零额外依赖,页面加载时就拿到数据,完全不用Ajax;缺点:全局变量如果管理不好容易污染空间,但用服务封装后基本没问题。
如果你想更贴合Angular的最佳实践,不想碰全局window对象,可以用Angular的constant或者value来注入常量。
步骤:
- 还是在Razor视图里,在Angular模块加载之后,添加这段脚本:
<script> // 给Angular根模块注册一个常量 angular.module('yourAppModuleName').constant('appConstants', { transactionStatuses: @Html.Raw(Json.Serialize(Model.TransactionStatuses)) }); </script>
注意把yourAppModuleName换成你实际的Angular模块名。
- 在Angular的服务或组件里,直接注入这个常量:
import { Injectable, Inject } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class GlobalConstantsService { constructor(@Inject('appConstants') private constants: any) {} get transactionStatuses() { return this.constants.transactionStatuses; } }
这个方案完全遵循Angular的依赖注入机制,代码更整洁,也更容易测试。
如果你的项目是先构建Angular再部署到ASP.NET上,可以让ASP.NET动态生成Angular的environment.ts文件。
比如先在ASP.NET项目里创建一个模板文件environment.template.ts:
export const environment = { production: false, transactionStatuses: {{TRANSACTION_STATUSES}} };
然后在ASP.NET的启动逻辑里,读取这个模板,把{{TRANSACTION_STATUSES}}替换成从数据库查出来的JSON字符串,生成最终的environment.ts文件,再让Angular加载这个文件。
之后在Angular里直接导入环境常量就行:
import { environment } from '../environments/environment'; // 使用常量 console.log(environment.transactionStatuses);
这个方案适合需要构建后动态配置的场景,不过步骤稍微繁琐一点。
内容的提问来源于stack exchange,提问作者JustLearning

