在Angular中,作为索引类型导入的json文件始终返回undefined

时间:2018-10-24 19:09:26

标签: json angular typescript

您将在底部找到在自己的设备上进行复制的说明。


我有一个使用Angular CLI创建的基本Angular项目,运行在TypeScript 3.1.3上,除了类和json文件外,没有做太多其他事情。

我在Angular CLI中使用以下命令创建了ResourcesServiceService类:

ng generate service Resources

我基本上是使用它来加载json文件,作为本地化的一种方式(而不是使用Angular未完成的内置国际化功能)。

以下是我的课程以及json文件:

ResourcesBundle.json

{
    "label.changeLanguage": "Change language",
    "label.education": "Education",
    "label.experience": "Experiences",
    "label.skills": "Skills",
    "label.summary": "Summary",
    "label.language.english": "English",
    "label.language.french": "French"
}

resources.service.ts

import * as resources from '../assets/resources/ResourcesBundle.json';

@Injectable({
    providedIn: 'root'
})

export class ResourcesService {

    constructor() {}

    public getString(label: string): string {
        let resource: string = resources[label];
        return resource;
    }
}

当然,为了能够以这种方式导入json文件,我在tsconfig.json中设置了"resolveJsonModule": true

该服务本身运行正常。我可以注入它并调用getString方法,它正在运行而没有任何错误。

但是,无论我将什么值传递给getString方法,返回的值始终为undefined。我什至尝试对label = 'label.summary'的值进行硬编码,但它仍返回undefined。唯一正常运行的时间是当我直接在方括号之间写入字符串时:

let resource: string;
label = 'label.summary';
resource = resources[label]; // resource == undefined
resource = resources['label.summary']; // resource == 'Summary'

在VSCode上的TS中,resources的内容如下:

    label.changeLanguage
    label.education
    label.experience
    label.language.english
    label.language.french
    label.skills
    label.summary

使用console.log(resources)时,控制台在Firefox上显示以下内容:

    Object {
            label.changeLanguage: "Change language"
            label.education: "Education"
            label.experience: "Experience"
            label.language.english: "English"
            label.language.french: "French"
            label.skills: "Skills"
            label.summary: "Summary"
    }

因此json已正确加载,但只能与硬编码字符串一起使用。

我发现的唯一其他解决方案是放弃json文件并直接在代码中初始化索引类型:

private resources: { [key: string]: string } = {
    'label.changeLanguage': 'Change language',
    'label.education': 'Education',
    'label.experience': 'Experiences',
    'label.skills': 'Skills',
    'label.summary': 'Summary',
    'label.language.english': 'English',
    'label.language.french': 'French'
};

但是,我根本不认为这是个好方法...

对于导入的json文件,为什么在使用变量时它总是返回undefined?否则,为什么它仅适用于括号之间的硬编码字符串?


修改:

您会在下面找到指向演示项目的stackblitz链接:

https://stackblitz.com/edit/angular-h2aspf?file=tsconfig.json

如果在浏览器上运行它,它将正常工作(控制台将正确显示Change language)。

但是,如果下载并在本地运行它,您会注意到控制台将改为显示undefined

要在本地运行:

  • 您必须具有npm和Angular CLI
  • 下载stackblitz演示并将其解压缩到一个文件夹中
  • 在项目文件夹中运行npm i
  • 运行ng serve --open
  • 在浏览器中打开控制台,它应该显示undefined,而不是预期值(在stackblitz上为Change language

1 个答案:

答案 0 :(得分:3)

编辑:

根据对Angular CLI问题的评论,一种解决方法是在tsconfig.json中设置"esModuleInterop": true,并将import语句更改为:

import * as resources from '../assets/resources/ResourcesBundle.json';

对此:

import resources from '../assets/resources/ResourcesBundle.json';

原始答案:

在不同设备上多次检查后,我认为这是与Angular直接相关的错误(当前版本:7.0.2)。

再次以我在问题中给出的示例为例:

https://stackblitz.com/edit/angular-h2aspf?file=tsconfig.json

在浏览器上,此演示在控制台上输出Change language

在语言环境设备上:

  • 下载stackblitz演示并将其解压缩到一个文件夹中
  • 在项目文件夹中运行npm i
  • 如果您使用ng serve运行,您会在网络浏览器控制台中注意到undefined
  • 停止Angular,然后再次使用ng serve --prod运行。 Web浏览器控制台现在可以正确输出Change language

我为此问题在GitHub上为Angular和Angular CLI项目打开了以下问题: