如何在 Angular 中异步加载 momentjs 时区数据
How to load momentjs timezones data asynchronously in Angular
我刚刚安装了软件包:
npm install moment-timezone --save
在 angular 组件中,我这样使用它:
import * as moment from 'moment-timezone';
moment().tz('America/New York');
我想这会将所有时区数据 (900+kB) 添加到供应商包中并减慢应用程序启动速度。
如何仅按需异步加载它?
我真的很想使用 NPM 解决方案,以便在更新 npm 包时自动更新数据库。没有人会记得手动更新时区数据库。
编辑:
@Dimanoid 的回答展示了如何在没有数据的情况下从 npm 导入 moment-timezone:
import * as moment from 'moment-timezone/moment-timezone';
以下是将数据作为延迟加载资产包含在内的方法:
修改angular.json -> projects -> yourprojects -> architect -> build -> options:
"assets": [
"src/favicon.ico",
"src/assets/i18n",
{ //add this
"glob": "latest.json",
"input": "node_modules/moment-timezone/data/packed",
"output": "assets/moment-timezone"
}
]
从资产文件夹按需请求:
import * as moment from 'moment-timezone/moment-timezone';
import { PlatformLocation } from '@angular/common';
export class MyComponent implements OnInit {
constructor(private platformLocation: PlatformLocation) {
}
ngOnInit(){
//you can use @angular/http instead of fetch
fetch(this.platformLocation.getBaseHrefFromDOM() + 'assets/moment-timezone/latest.json')
.then(time => time.json())
.then(timeZoneData => {
moment.tz.load(timeZoneData);
});
}
}
好吧,为了不将评论转化为论坛,让我们总结一下。
您可以从官方网站下载库,将它放在您的代码树中的某处,导入它然后从后端加载 tz-bundle 并调用 moment.tz.load()
初始化 moment-timezon
然后使用它.
import 'moment';
import * as moment from '../../assets/moment-timezone-nodata';
ngOnInit() {
this.loadTzBundle().subscribe(data => {
moment.tz.load(data);
});
}
为了说明这一点,我做了一个最小的工作示例:https://stackblitz.com/edit/moment-tz-data-loading
编辑
我查看了源代码,实际上 npm 包将 lib 和数据分开了。它只是在您导入默认值时加载数据。
var moment = module.exports = require("./moment-timezone");
moment.tz.load(require('./data/packed/latest.json'));
所以我认为你可以安装包并加载没有数据的库。
import * as moment from 'moment-timezone/moment-timezone';
我更新了示例。
我刚刚安装了软件包:
npm install moment-timezone --save
在 angular 组件中,我这样使用它:
import * as moment from 'moment-timezone';
moment().tz('America/New York');
我想这会将所有时区数据 (900+kB) 添加到供应商包中并减慢应用程序启动速度。
如何仅按需异步加载它?
我真的很想使用 NPM 解决方案,以便在更新 npm 包时自动更新数据库。没有人会记得手动更新时区数据库。
编辑:
@Dimanoid 的回答展示了如何在没有数据的情况下从 npm 导入 moment-timezone:
import * as moment from 'moment-timezone/moment-timezone';
以下是将数据作为延迟加载资产包含在内的方法:
修改angular.json -> projects -> yourprojects -> architect -> build -> options:
"assets": [ "src/favicon.ico", "src/assets/i18n", { //add this "glob": "latest.json", "input": "node_modules/moment-timezone/data/packed", "output": "assets/moment-timezone" } ]
从资产文件夹按需请求:
import * as moment from 'moment-timezone/moment-timezone'; import { PlatformLocation } from '@angular/common'; export class MyComponent implements OnInit { constructor(private platformLocation: PlatformLocation) { } ngOnInit(){ //you can use @angular/http instead of fetch fetch(this.platformLocation.getBaseHrefFromDOM() + 'assets/moment-timezone/latest.json') .then(time => time.json()) .then(timeZoneData => { moment.tz.load(timeZoneData); }); } }
好吧,为了不将评论转化为论坛,让我们总结一下。
您可以从官方网站下载库,将它放在您的代码树中的某处,导入它然后从后端加载 tz-bundle 并调用 moment.tz.load()
初始化 moment-timezon
然后使用它.
import 'moment';
import * as moment from '../../assets/moment-timezone-nodata';
ngOnInit() {
this.loadTzBundle().subscribe(data => {
moment.tz.load(data);
});
}
为了说明这一点,我做了一个最小的工作示例:https://stackblitz.com/edit/moment-tz-data-loading
编辑
我查看了源代码,实际上 npm 包将 lib 和数据分开了。它只是在您导入默认值时加载数据。
var moment = module.exports = require("./moment-timezone");
moment.tz.load(require('./data/packed/latest.json'));
所以我认为你可以安装包并加载没有数据的库。
import * as moment from 'moment-timezone/moment-timezone';
我更新了示例。