从 Cloud Firestore 在 MatDatepicker 中加载时间戳 |火力基地

Posted

技术标签:

【中文标题】从 Cloud Firestore 在 MatDatepicker 中加载时间戳 |火力基地【英文标题】:Load timestamp in MatDatepicker from Cloud Firestore | Firebase 【发布时间】:2018-11-13 06:09:39 【问题描述】:

不加载从 Cloud Firestore 返回的日期。

在我将依赖项从 package.json 更新到最新版本后,我在 Angular 6 中对我的应用程序产生了很大影响。

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

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

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

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

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

有没有办法将 Datepicker 的类型更改为 Timestamp? 否则我无法从 Cloud Firestore 接收时间戳类型的值。

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 类型? material.angular.io/components/datepicker/overview var date = new Date(unix_timestamp*1000);我不确定你的问题,但如果你想从时间戳中获取日期,就是这样。 更新前返回一个Date()对象。我不想遍历从 Firebase 返回的所有记录并变成一个 Date() 对象。 那么,您想要来自 DatePicker 的时间戳吗? 【参考方案1】:

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

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返回的数据。 如果你不发布如何构建数据,我帮不了你【参考方案2】:

Luiz,我刚刚在升级旧应用时遇到了你的问题,并遇到了同样的问题。

对我来说,我一次只处理一个日期,因此我使用时间戳上的toDate() 方法来允许日期选择器使用它。尝试看看是否有办法可以集体执行此操作(我相信您早就解决了这个问题,但想发帖以防其他人发现这有帮助)。

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

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

【讨论】:

【参考方案3】:

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

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

一旦我从 Firebase 的文档中获取数据,我将无法访问诸如“”或“纳秒”之类的时间戳属性:

t seconds: 1591945200, nanoseconds: 0 

下一步,我将能够根据从 Firebase 文档收到的时间戳创建一个 Date 对象。

...    
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));
          
      );
    

最后一步很简单,我只是将“日期”分配给 [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

【讨论】:

【参考方案4】:

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

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

value string | number | Date :要格式化的日期,作为日期或数字(自 UTC 纪元以来的毫秒数)或 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')
);

【讨论】:

以上是关于从 Cloud Firestore 在 MatDatepicker 中加载时间戳 |火力基地的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Cloud Firestore 上的对象中检索值?迅速

Flutter - 从 Cloud Firestore 读取嵌套地图

如何从 Javascript 在 Cloud Firestore 中创建集合?

从 Cloud Firestore 在 MatDatepicker 中加载时间戳 |火力基地

如何使用 Cloud Function 将数据从 Firebase Firestore 索引到 Elastic App Search?

从 Cloud Firestore 检索时,Recycler View 未加载数据