从Cloud Firestore加载时间戳到MatDatepicker | Firebase

9

无法加载Cloud Firestore返回的日期。

在我将依赖项更新为最新版本后,我的Angular 6应用程序受到了很大影响。

我无法将Timestamp类型的值加载到由Cloud Firestore返回的DatePicker类型的字段中。

在升级之前,我返回了一个Date()对象,更新后返回了一个Cloud Firestore Timestamp

我相信在这次更新中Firebase返回的类型发生了一些改变。

DatePicker字段必须接收Date()对象,而不是Timestamp

我需要遍历从Cloud Firestore返回的所有记录并调用toDate()方法来获取Date()对象并将其加载到DatePicker中。

是否有一种方法可以将Datepicker的类型更改为Timestamp? 否则,我将无法从Cloud Firestore接收到Timestamp类型的值。

enter image description here

package.json:

{
  "name": "myapp",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve --open",
    "start-hmr": "ng serve --hmr -e=hmr -sm=false",
    "start-hmr-sourcemaps": "ng serve --hmr -e=hmr",
    "build": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --dev",
    "build-stats": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --dev --stats-json",
    "build-prod": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --prod",
    "build-prod-stats": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --prod --stats-json",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "bundle-report": "webpack-bundle-analyzer dist/stats.json"
  },
  "private": true,
  "dependencies": {
    "@agm/core": "1.0.0-beta.2",
    "@angular/animations": "6.0.0",
    "@angular/cdk": "6.0.1",
    "@angular/common": "6.0.0",
    "@angular/compiler": "6.0.0",
    "@angular/core": "6.0.0",
    "@angular/flex-layout": "6.0.0-beta.15",
    "@angular/forms": "6.0.0",
    "@angular/http": "6.0.0",
    "@angular/material": "6.0.1",
    "@angular/material-moment-adapter": "6.0.1",
    "@angular/platform-browser": "6.0.0",
    "@angular/platform-browser-dynamic": "6.0.0",
    "@angular/router": "6.0.0",
    "@ngrx/effects": "6.0.0-beta.1",
    "@ngrx/router-store": "6.0.0-beta.1",
    "@ngrx/store": "6.0.0-beta.1",
    "@ngrx/store-devtools": "6.0.0-beta.1",
    "@ngx-translate/core": "10.0.1",
    "@swimlane/ngx-charts": "8.0.0",
    "@swimlane/ngx-datatable": "12.0.0",
    "@swimlane/ngx-dnd": "4.0.0",
    "@types/express": "4.11.1",
    "@types/prismjs": "1.9.0",
    "angular-calendar": "0.24.0",
    "angular-in-memory-web-api": "0.6.0",
    "angularfire2": "5.0.0-rc.9",
    "body-parser": "1.18.3",
    "body-parser-zlib": "1.0.2",
    "chart.js": "2.7.2",
    "classlist.js": "1.1.20150312",
    "core-js": "2.5.6",
    "creditcard.js": "2.1.3",
    "d3": "5.2.0",
    "express": "4.16.3",
    "firebase": "5.0.3",
    "firebase-admin": "5.12.1",
    "font-awesome": "4.7.0",
    "hammerjs": "2.0.8",
    "lodash": "4.17.10",
    "moment": "2.22.1",
    "ng2-charts": "1.6.0",
    "ng2-currency-mask": "5.3.1",
    "ngrx-store-freeze": "0.2.2",
    "ngx-color-picker": "6.0.0",
    "ngx-cookie-service": "1.0.10",
    "ngx-mask": "2.7.3",
    "ngx-toastr": "8.6.0",
    "perfect-scrollbar": "1.3.0",
    "prismjs": "1.14.0",
    "rxjs": "6.1.0",
    "rxjs-compat": "6.1.0",
    "typescript": "2.7.2",
    "web-animations-js": "2.3.1",
    "zone.js": "0.8.26"
  },
  "main": "server.js",
  "devDependencies": {
    "@angular-devkit/build-angular": "0.6.0",
    "@angular/cli": "6.0.3",
    "@angular/compiler-cli": "6.0.0",
    "@angular/language-service": "6.0.0",
    "@angularclass/hmr": "2.1.3",
    "@types/cookie-parser": "1.4.1",
    "@types/jasmine": "2.8.7",
    "@types/jasminewd2": "2.0.3",
    "@types/lodash": "4.14.108",
    "@types/node": "8.9.5",
    "codelyzer": "4.2.1",
    "jasmine-core": "2.99.1",
    "jasmine-spec-reporter": "4.2.1",
    "karma": "1.7.1",
    "karma-chrome-launcher": "2.2.0",
    "karma-coverage-istanbul-reporter": "1.4.2",
    "karma-jasmine": "1.1.2",
    "karma-jasmine-html-reporter": "0.2.2",
    "protractor": "5.3.1",
    "ts-node": "5.0.1",
    "tslint": "5.9.1",
    "webpack-bundle-analyzer": "2.11.1"
  }
}

什么是DatePicker类型? - Izio
https://material.angular.io/components/datepicker/overview - Luiz Ricardo Cardoso
var date = new Date(unix_timestamp*1000); 我不确定我理解你的问题,但如果你想从时间戳获取日期,这就是方法。 - Izio
更新之前返回了一个 Date() 对象。 我不想遍历从 Firebase 返回的所有记录并将其转换为 Date() 对象。 - Luiz Ricardo Cardoso
所以,您想从DatePicker获取时间戳? - Izio
显示剩余5条评论
4个回答

2

Luiz,我刚刚遇到了你的问题,因为我正在升级一个旧应用程序,并遇到了同样的问题。

对于我来说,我只处理一个日期,所以我使用时间戳上的toDate()方法使日期选择器能够使用它。尝试看看是否有一种方法可以批量执行此操作(我确定您已经解决了这个问题,但希望发布以便其他人找到此有用)。

在将更新保存到数据库中时,我可以使用firestore.Timestamp.fromDate(myDateValue)将它们保存回时间戳。

https://medium.com/@Idan_Co/using-firebase-timestamp-with-angular-bootstraps-datepicker-317336be9923可能有助于进一步理解,因为它对我有很大帮助。


0

我相信你的代码大概是这样的,所以只需要将时间戳转换为日期类型即可。

import {Component} from '@angular/core';
import {FormControl} from '@angular/forms';

/** @title Datepicker selected value */
@Component({
  selector: 'datepicker-value-example',
  templateUrl: 'datepicker-value-example.html',
  styleUrls: ['datepicker-value-example.css'],
})
export class DatepickerValueExample {
  date = new FormControl(new Date(unix_timestamp*1000)); // convert timestamp to date
  serializedDate = new FormControl((new Date()).toISOString());
}

HTML:

<mat-form-field>
  <input matInput [matDatepicker]="picker1" placeholder="Angular forms" [formControl]="date">
  <mat-datepicker-toggle matSuffix [for]="picker1"></mat-datepicker-toggle>
  <mat-datepicker #picker1></mat-datepicker>
</mat-form-field>

那么这样做是不行的,因为我使用FormBuilder来构建Cloud Firestore返回的数据。 - Luiz Ricardo Cardoso
如果您不发布如何构建数据的信息,我无法帮助您。 - Melchia

0

要将时间戳转换为日期选择器使用的日期格式,您需要使用@angular/common中的formatDate。这是Angular - formatDate的文档。

根据区域设置规则格式化日期。

  • value string | number | Date :要格式化的日期,可以是一个日期对象、毫秒数或ISO date-time string

  • format string :要包含的日期时间组件。有关详细信息,请参见DatePipe

  • locale string :用于使用区域设置格式规则的区域设置代码。

  • timezone string :时区。与GMT的时区偏移(例如+0430)或标准UTC/GMT或美国大陆时区缩写。如果未指定,则使用主机系统设置。[可选]默认值为undefined

    formatDate(value: string | number | Date, format: string, locale: string, timezone?: string): string

这是使用formBuilder修补输入值的示例。

this.exeampleForm.patchValue({
    date: formatDate(new Date(this.exeampleForm.get('date').value).setHours(12), 'dd-MM-yyyy@HH:mm:ss', 'fr_FR')
});

0

我对Angular 9还是比较新手,我遇到了和你一样的问题。我知道有很多方法可以解决这个问题,但我不想花太多时间寻找花哨的方法。我决定选择最简单的方法,同时我的 'dateProp' 类型并不是那么重要,所以我将其从 'Date' 改为 'any'。

export interface ExampleModel {
  id: string;
  ...
  dateProp: any;
  ...
}

一旦我从Firebase的文档中获取了数据,我就可以轻松访问时间戳属性,例如'seconds'或'nanoseconds':

t {seconds: 1591945200, nanoseconds: 0} 

接下来,我将能够基于Firebase文档收到的时间戳创建一个日期对象。
...    
public date;
public exampleModel: ExampleModel;

constructor(private exampleService: ExampleService) { }
ngOnInit() {
    ...
    if (this.exampleId != null){
      this.exampleService
        .getExampleById(this.exampleId)
        .subscribe((example: ExampleModel) => {
          this.exampleModel = example;
          if (this.exampleModel !== undefined){
            this.date = new FormControl(new Date(this.exampleModel?.dateProp.seconds * 1000));
          }
      });
    }

最后一步很简单,我只需要将“date”分配给[formControl]。
 <mat-form-field>
    <input name="exampleDate" matInput [matDatepicker]="exampleDatePicker" [formControl]="date" />
    <mat-datepicker-toggle matSuffix [for]="exampleDatePicker"></mat-datepicker-toggle>
    <mat-datepicker #exampleDatePicker></mat-datepicker>
  </mat-form-field>

这是两年前的问题,但我仍然写下这个解决方案,因为我希望我的解决方案能够帮助下一个遇到和我一样棘手问题的人。:D


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接