Come utilizzare la libreria moment.js nell'app angolare 2 dattiloscritta?


231

Ho provato ad usarlo con i collegamenti dattiloscritti:

npm install moment --save
typings install moment --ambient -- save

test.ts:

import {moment} from 'moment/moment';

E senza:

npm install moment --save

test.ts:

var moment = require('moment/moment');

Ma quando chiamo moment.format (), ottengo un errore. Dovrebbe essere semplice, qualcuno può fornire una combinazione di riga di comando / importazione che funzionerebbe?


1
condividi il tuo errore per favore
basarat

1
Se installo moment.d.ts e utilizzo import, visualizzo l'errore di compilazione ERRORE in ... / typings / browser / ambient / moment / moment.d.ts (9,21): errore TS2503: impossibile trovare lo spazio dei nomi 'moment' . E se non installo le tipizzazioni e uso richiesto, ottengo Uncaught TypeError: moment.format non è una funzione
Sergey Aldoukhov

Ci sono troppe vecchie risposte qui. Si prega di guardare qui: github.com/angular/angular-cli/wiki/…
Didia

3
La risposta di Hinrich ha funzionato per me con ng4 (da giugno 2017) stackoverflow.com/a/43257938/1554495
tenderloin

SergeyAldoukhov è ancora la risposta migliore? sicuramente @ Hinrich è?
jenson-button-event,

Risposte:


513

Aggiornamento aprile 2017:

A partire dalla versione 2.13.0, Moment include un file di definizione dattiloscritto. https://momentjs.com/docs/#/use-it/typescript/

Basta installarlo con npm, nel tipo di console

npm install --save moment

E poi nella tua app Angular, l'importazione è facile come questa:

import * as moment from 'moment';

Ecco fatto, ottieni pieno supporto per Typescript!

Modifica bonus: per digitare una variabile o proprietà come Momentin Typescript puoi farlo, ad esempio:

let myMoment: moment.Moment = moment("someDate");

1
è importante aggiungerlo al file app.module e importare l'array? o puoi semplicemente importarlo all'interno di un componente e usarlo?
Katherine R,

3
@Katherine R Puoi usarlo in qualsiasi file, non è angolare specifico.
Hinrich,

Ora, che dire dei plugin moment, come moment-round?
Greywire,

2
In realtà questa risposta non è specifica angolare, si applica a qualsiasi progetto Typescript.
Hinrich,

Fantastico, e come uso la pipe sul template?
vladanPro

98

momentè una risorsa globale di terze parti. Il momento in cui l'oggetto vive windownel browser. Pertanto non è corretto importnell'applicazione angular2. Invece includi il <script>tag nel tuo html che caricherà il file moment.js.

Per rendere felice TypeScript puoi aggiungere

declare var moment: any;

nella parte superiore dei tuoi file dove lo usi per interrompere gli errori di compilazione, oppure puoi usarli

///<reference path="./path/to/moment.d.ts" />

oppure usa tsd per installare il file moment.d.ts che TypeScript potrebbe trovare da solo.

Esempio

import {Component} from 'angular2/core';
declare var moment: any;

@Component({
    selector: 'example',
    template: '<h1>Today is {{today}}</h1>'
})
export class ExampleComponent{
    today: string = moment().format('D MMM YYYY');
}

Assicurati solo di aggiungere il tag script nel tuo html o il momento non esisterà.

<script src="node_modules/moment/moment.js" />

Caricamento del modulo moment

Innanzitutto è necessario impostare un caricatore di moduli come System.js per caricare i file commonjs del momento

System.config({
    ...
    packages: {
        moment: {
            map: 'node_modules/moment/moment.js',
            type: 'cjs',
            defaultExtension: 'js'
        }
    }
});

Quindi importare il momento nel file dove necessario

import * as moment from 'moment';

o

import moment = require('moment');

MODIFICARE:

Ci sono anche opzioni con alcuni bundler come Webpack o builder SystemJS o Browserify che manterranno il momento fuori dall'oggetto finestra. Per ulteriori informazioni al riguardo, visitare i rispettivi siti Web per istruzioni.


3
Ciò è possibile, ma è molto lungo in quanto è necessario disporre di un caricatore di moduli come il Systemcaricamento nella versione del momento del nodo commonjs e quindi si sarà in grado di fare riferimento a esso import * as moment from 'moment';o con import moment = require('moment');cui a tutti gli effetti sono identici, ma è necessario alcune sottili differenze nel dattiloscritto.
SnareChops

@SnareChops typings install moment --ambient -- savenon typingsestrae il file di definizione e crea il riferimento a ///<reference path="./path/to/moment.d.ts" />? Sto riscontrando lo stesso errore durante l'esecuzionenpm run tsc
Shawn Northrop,

Questo è fuorviante; non c'è niente di sbagliato nel importmomento ing.
Stiggler

2
Questa risposta è incompleta perché devi usare Digitazioni per gestire la definizione del momento. Inoltre, non è necessario importare nulla. Per favore, vedi la mia risposta qui sotto .
Bernardo Pacheco,

8
Questa risposta è fuorviante, il fatto che moment sia una variabile globale non significa che devi "caricarla" come tag di script. Puoi, e dovresti, raggrupparlo in un file del fornitore se stai usando una sorta di bundler (Webpack). Puoi anche risolvere il problema dell'assegnazione globale se usi il webpack e un caricatore appropriato.
Shlomi Assaf,

49

Quanto segue ha funzionato per me.

Innanzitutto, installa le definizioni dei tipi per il momento.

typings install moment --save

(Nota: NON --ambient)

Quindi, per ovviare alla mancanza di una corretta esportazione:

import * as moment from 'moment';

2
Ho dovuto fare import moment from "moment";invece per farlo funzionare.
Aetherix,

3
Questa risposta è incompleta perché non è necessario importare nulla. Per favore, vedi la mia risposta qui sotto .
Bernardo Pacheco,

1
Anche ogni iterazione di ionico 2 beta / angolare 2 rc sembrava portare un nuovo modo di importare le cose, quindi potresti dover provare alcuni di questi suggerimenti anche se un punto erano una volta la risposta più aggiornata
discodane

import * as moment from 'moment';è la chiave.
nima,

Sto riscontrando Impossibile trovare "moment" ("npm") nel registro. quando provo a installare le definizioni, aiutatemi per favore
Sebastián Rojas,

28

Vorrei andare con il seguente:

npm install moment --save

All'array del tuo systemjs.config.jsfile mapaggiungi:

'moment': 'node_modules/moment'

a packagesArray Aggiungi:

'moment': { defaultExtension: 'js' }

Nel tuo componente.ts usa: import * as moment from 'moment/moment';

e basta. Puoi utilizzare dalla classe del tuo componente:

today: string = moment().format('D MMM YYYY');


25

Stiamo usando i moduli ora,

provare import {MomentModule} from 'angular2-moment/moment.module';

dopo npm install angular2-moment

http://ngmodules.org/modules/angular2-moment


76
Questo è insufficiente, perché installa solo tubi. Apparentemente, non puoi lavorare con le date Moment nei tuoi moduli in questo modo.
ntaso,

1
mi piacerebbe qualche consiglio su come usare i filtri angular2-moment nella classe componente
trickpatty

3
questo dovrebbe essere: importare {MomentModule} da 'angular2-moment / moment.module';
yasser,

1
Questa non dovrebbe essere più la risposta scelta. Dai un'occhiata alla risposta di @Hinrich. npm install moment --save, npm install @types/moment --save Stackoverflow.com/questions/35166168/...
jamesjansson

invece di installare un wrapper dovrebbe essere comeimport * as moment from 'moment';
M. Atif Riaz,

22

Per usarlo in un Typescriptprogetto dovrai installare moment:

npm install moment --save

Dopo l'installazione, puoi usarlo in qualsiasi .tsfile dopo averlo importato:

import * as moment from "moment";


1
Nota ** @ types / moment @ 2.13.0: questa è una definizione di tipi di stub per Moment ( github.com/moment/moment ). Moment fornisce le proprie definizioni dei tipi, quindi non è necessario installare @ types / moment!
Winnemucca,

1
Grande! Ecco il riferimento ufficiale: momentjs.com/docs/#/use-it/typescript
Andrea

14

--- Aggiornamento 11/01/2017

La digitazione è ora obsoleta ed è stata sostituita da npm @types . D'ora in poi ottenere dichiarazioni di tipo non richiederà strumenti oltre a npm. Per utilizzare Moment non è necessario installare le definizioni dei tipi tramite @types poiché Moment fornisce già le proprie definizioni dei tipi.

Quindi, si riduce a soli 3 passaggi:

1 - Momento di installazione che include le definizioni del tipo:

npm install moment --save

2 - Aggiungi il tag script nel tuo file HTML:

<script src="node_modules/moment/moment.js" />

3 - Ora puoi semplicemente usarlo. Periodo.

today: string = moment().format('D MMM YYYY');

--- Risposta originale

Questo può essere fatto in soli 3 passaggi:

1 - Installa definizione momento - file * .d.ts :

typings install --save --global dt~moment dt~moment-node

2 - Aggiungi il tag script nel tuo file HTML:

<script src="node_modules/moment/moment.js" />

3 - Ora puoi semplicemente usarlo. Periodo.

today: string = moment().format('D MMM YYYY');

Sto riscontrando problemi con la versione di digitazioni disponibile su dt. Sta usando una vecchia versione di moment che non ha i nuovi metodi che voglio usare. Se faccio come raccomandato da loro ( momentjs.com/docs/#/use-it/system-js ) l'applicazione viene compilata, ma non viene caricata nel browser. Sto quasi per raggiungere un vicolo cieco ...
Fabricio,

Non sono riuscito a far funzionare il tag di script con cli angolare. Ha più senso che importare però
Winnemucca il

@Bernardo Ho provato a seguire i tuoi passi e ho installato moment.js. Dopo declare var moment;Tuttavia, le digitazioni non funzionano per me. Dopo aver digitato moment().nessun intellisense. Immagino che mi manchi qualche passo qui.
Shyamal Parikh,

Abbastanza sicuro che non funzioni, come fa il web pack a includerlo nei moduli del nodo build?
johnny 5

12

Per Angular 7+ (supporta anche 8 e 9) :

1: Installa il momento tramite comando npm install moment --save

2: non aggiungere nulla in app.module.ts

3: aggiungi semplicemente la dichiarazione di importazione in cima al tuo componento qualsiasi altro file come questo:import * as moment from 'moment';

4: ora puoi usare momentovunque nel tuo codice. Proprio come:

myDate = moment(someDate).format('MM/DD/YYYY HH:mm');


Ho dovuto importare in questo modo: import * as moment_ from 'moment'; const moment = moment_;Altrimenti stavo ottenendoError: Cannot call a namespace ('moment')
Snook il

Molto strano da ascoltare. moment_è solo un nome letterale. Può essere qualsiasi cosa, credo ...
Rahmat Ali,

1
Basta essere consapevoli del fatto che import * as moment from 'moment';aumentare la dimensione del pacchetto di ~ 500kb. C'è un buon articolo che spiega il problema con una soluzione medium.jonasbandi.net/…
Kosmonaft

9

con CLI

> npm install moment --save

in app.module

import * as moment from 'moment';

providers: [{ provide: 'moment', useValue: moment }]

nel componente

constructor(@Inject('moment') private moment)

in questo modo importa un momento una volta

AGGIORNAMENTO Angolare => 5

{
   provide: 'moment', useFactory: (): any => moment
}

Per me lavora in prod con aot e anche con universale

Non mi piace usare nessun momento ma usando il momento

Error   Typescript  Type 'typeof moment' is not assignable to type 'Moment'. Property 'format' is missing in type 'typeof moment'.

Ottengo l' Parameter 'moment' implicitly has an 'any' typeerrore.
Azimuth,

Questo funziona per te in modalità prod? Funzionava bene in modalità dev, ma quando eseguo la mia app in modalità prod non riesce. Anche la mia app ha moduli caricati in modo pigro (nel caso in cui sia importante). il momento finisce per essere nullo.
jbgarr, l'

@jbgarr Ho provato in un modulo pigro come il costruttore (@Inject ('moment') momento privato) {console.log ('date', moment ()); } senza problemi
Whisher l'

8

La libreria angular2-moment ha pipe come {{myDate | amTimeAgo}} da utilizzare nei file .html.

È possibile accedere alle stesse pipe come funzioni Typescript all'interno di un file di classe componente (.ts). Innanzitutto installa la libreria come indicato:

npm install --save angular2-moment

In node_modules / angular2-moment ora ci saranno file ".pipe.d.ts" come calendar.pipe.d.ts , date-format.pipe.d.ts e molti altri.

Ognuno di questi contiene il nome della funzione Typescript per la pipe equivalente, ad esempio DateFormatPipe () è la funzione per amDateFormatPipe .

Per utilizzare DateFormatPipe nel progetto, importalo e aggiungilo ai tuoi fornitori globali in app.module.ts:

import { DateFormatPipe } from "angular2-moment";
.....
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}, ...., DateFormatPipe]

Quindi, in qualsiasi componente in cui si desidera utilizzare la funzione, importarla in primo piano, iniettare nel costruttore e utilizzare:

import { DateFormatPipe } from "angular2-moment";
....
constructor(.......,  public dfp: DateFormatPipe) {
    let raw = new Date(2015, 1, 12);
    this.formattedDate = dfp.transform(raw, 'D MMM YYYY');
}

Per utilizzare una qualsiasi delle funzioni seguire questo processo. Sarebbe bello se ci fosse un modo per accedere a tutte le funzioni, ma nessuna delle soluzioni di cui sopra ha funzionato per me.


Questo è fantastico grazie! Ovunque per angular2 moment ti mostra come usarlo solo su template. Il tuo post molto utile mi ha mostrato come usarlo per manipolare il valore prima di inviarlo al modello.
Andrew Junior Howard,

@royappa Vedo alcuni usando il modulo Pipes e alcuni usando solo il momento per accedervi in ​​Typescript. Capisco che stai dicendo che puoi usare la versione di Pipes in Typescript ma quale sarebbe il danno nell'installare entrambi?
Jacques,

5

Se stai bene aggiungendo altri pacchetti di terze parti, ho usato la libreria angular2-moment . L'installazione è stata piuttosto semplice e dovresti seguire le ultime istruzioni su README. Di conseguenza ho anche installato le digitazioni .

Ha funzionato come un incantesimo per me e ha appena aggiunto alcun codice per farlo funzionare.


5

Non sono sicuro che questo sia ancora un problema per le persone, tuttavia ... Utilizzando SystemJS e MomentJS come libreria, questo mi ha risolto

/*
 * Import Custom Components
 */
import * as moment from 'moment/moment'; // please use path to moment.js file, extension is set in system.config

// under systemjs, moment is actually exported as the default export, so we account for that
const momentConstructor: (value?: any) => moment.Moment = (<any>moment).default || moment;

Funziona bene da lì per me.


5

per angular2 RC5 questo ha funzionato per me ...

primo momento di installazione tramite npm

npm install moment --save

Quindi importare il momento nel componente in cui si desidera utilizzarlo

import * as moment from 'moment';

infine configurare il momento in systemjs.config.js "map" e "pacchetti"

// map tells the System loader where to look for things
  var map = {
  ....
  'moment':                     'node_modules/moment'
  };
  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    ...
    'moment':                       { main:'moment', defaultExtension: 'js'}
  };

Qualche idea su quale sia il passaggio equivalente per il webpack?
Bharat Geleda,

@BharatGeleda Non c'è bisogno di fare nulla con il webpack. Usando Angular2 e angular-cli ho dovuto solo installare e importare npm. Non avevo bisogno di alcuna digitazione poiché l'ultima versione di moment supporta il dattiloscritto.
Stanislasdrg Ripristina Monica l'

1
L'unica soluzione che mi ha fatto importare un altro locale: import 'moment/locale/de.js';Grazie!
iBaff,

4

Oltre alla risposta di SnareChop, ho dovuto modificare il file delle tipizzazioni per momentjs.

In moment-node.d.tsho sostituito:

export = moment;

con

export default moment;


4

La mia versione dell'utilizzo di Moment in Angular

npm i moment --save

import * as _moment from 'moment';

...

moment: _moment.Moment = _moment();

constructor() { }

ngOnInit() {

    const unix = this.moment.format('X');
    console.log(unix);    

}

Primo momento di importazione come _moment, quindi dichiarare la momentvariabile con tipo _moment.Momentcon un valore iniziale di _moment().

L'importazione semplice di moment non ti darà alcun completamento automatico, ma se dichiarerai il momento con l' Momentinterfaccia del tipo dallo _momentspazio dei nomi dal 'moment'pacchetto inizializzato con lo spazio dei nomi del momento richiamato, _moment()otterrai il completamento automatico delle API di moment.

Penso che questo sia il modo più angolare di usare moment senza usare @types typingso provider angolari, se stai cercando il completamento automatico per librerie javascript vanilla come moment.


L'installazione dei tipi ti consentirà di accedere al completamento automatico:npm install @types/moment --save
jamesjansson

3

Prova ad aggiungere "allowSyntheticDefaultImports": trueal tuo tsconfig.json.

Cosa fa la bandiera?

Questo in sostanza dice al compilatore TypeScript che va bene usare un'istruzione di importazione ES6, ad es

import * as moment from 'moment/moment';

su un modulo CommonJS come Moment.js che non dichiara un'esportazione predefinita. Il flag influenza solo il controllo del tipo, non il codice generato.

È necessario se si utilizza SystemJS come caricatore di moduli. Il flag si attiverà automaticamente se dici al compilatore TS che usi SystemJS:

"module": "system"

Ciò rimuoverà anche eventuali errori generati dagli IDE se sono configurati per l'utilizzo di tsconfig.json.


2

per angular2 con systemjs e jspm doveva fare:

import * as moment_ from 'moment';
export const moment =  moment_["default"];

var a = moment.now();
var b = moment().format('dddd');
var c = moment().startOf('day').fromNow();

2

Per gli utenti della CLI ANGOLARE

L'uso di librerie esterne è nella documentazione qui:

https://github.com/angular/angular-cli/wiki/stories-third-party-lib

Installa semplicemente la tua libreria tramite

npm installa lib-name --save

e importalo nel tuo codice. Se la libreria non include le digitazioni, è possibile installarle utilizzando:

npm installa lib-name --save

npm install @ types / lib-name --save-dev

Quindi apri src / tsconfig.app.json e aggiungilo alla matrice dei tipi:

"types": ["lib-name"]

Se la libreria per cui hai aggiunto le digitazioni deve essere utilizzata solo nei test e2e, utilizza invece e2e / tsconfig.e2e.json. Lo stesso vale per unit test e src / tsconfig.spec.json.

Se la libreria non dispone di digitazioni disponibili su @ types /, puoi comunque utilizzarla aggiungendo manualmente le digitazioni:

Innanzitutto, crea un file typings.d.ts nella cartella src /.

Questo file verrà automaticamente incluso come definizione di tipo globale. Quindi, in src / typings.d.ts, aggiungi il seguente codice:

dichiarare il modulo 'typeless-package';

Infine, nel componente o nel file che utilizza la libreria, aggiungi il seguente codice:

import * as typelessPackage da 'typeless-package'; typelessPackage.method ();

Fatto. Nota: potrebbe essere necessario o utile trovare ulteriori digitazioni per la libreria che si sta tentando di utilizzare.


Dai un'occhiata a questo articolo se hai bisogno di istruzioni dettagliate. medium.com/@jek.bao.choo/…
wag0325

1

Ho seguito i consigli per consentire allowSyntheticDefaultImports (dal momento che non ci sono esportazioni dal momento da usare per me), usando System. Quindi ho seguito il consiglio di qualcuno di usare:

import moment from 'moment';

Con il momento mappato nella mia configurazione di system.js. Le altre dichiarazioni di importazione non funzionerebbero per me, per qualche motivo


Questa è l'ultima risposta in questo momento, ma l'unica che funziona!
TJL,

1

Per me ha funzionato:

typings install dt~moment-node --save --global

Il nodo momento non esiste nel repository delle tipizzazioni. È necessario reindirizzare a Definitely Typed per farlo funzionare utilizzando il prefisso dt.


1

Con systemjs quello che ho fatto è, all'interno del mio systemjs.config ho aggiunto la mappa per moment

map: {
   .....,
   'moment': 'node_modules/moment/moment.js',
   .....
}

E poi puoi facilmente importare momentsemplicemente

import * as moment from 'moment'

1

So che è un vecchio thread, ma per me la soluzione più semplice che effettivamente ha funzionato è stata:

  1. Installarlo per primo npm install moment --save
  2. Nei miei componenti che lo richiedono da node_modules e lo uso:
const moment = require('../../../node_modules/moment/moment.js');

@Component({...})
export class MyComponent {
   ...
   ngOnInit() {
       this.now = moment().format();
   }
   ...
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.