Як користуватися бібліотекою moment.js у додатку 2-х кутових машинописів?


231

Я намагався використовувати його з прив'язками машинопису:

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

test.ts:

import {moment} from 'moment/moment';

І без:

npm install moment --save

test.ts:

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

Але коли я дзвоню moment.format (), я отримую помилку. Чи повинен бути простим, чи може хтось надати комбінацію командного рядка та імпорту, яка б працювала?


1
поділіться вашою помилкою, будь ласка
Басарат

1
Якщо я встановлю moment.d.ts і використовую імпорт, я отримую помилку компіляції ERROR у ... / typping / browser / ambient / moment / moment.d.ts (9,21): error TS2503: Неможливо знайти простір імен 'moment' . І якщо я не встановлюю типізації та використовую вимагаю, я отримую Uncaught TypeError: moment.format не є функцією
Сергій Алдухов

Тут є занадто багато старої відповіді. Будь ласка, дивіться тут: github.com/angular/angular-cli/wiki/…
Дідія

3
Відповідь Hinrich працював для мене з NG4 (станом на червень 2017 року) stackoverflow.com/a/43257938/1554495
вирізка

СергійАлдухов - це все-таки найкраща відповідь? напевно @ Гінріх є?
jenson-button-event

Відповіді:


513

Оновлення квітня 2017 року:

Станом на версію 2.13.0, Момент включає файл визначення машинопису. https://momentjs.com/docs/#/use-it/typescript/

Просто встановіть його з npm, у тип консолі

npm install --save moment

І тоді ваш додаток Angular імпортується так само просто:

import * as moment from 'moment';

Це все, ви отримуєте повну підтримку Typescript!

Редагування бонусу: Щоб ввести змінну або властивість, як Momentу Typescript, ви можете зробити це, наприклад:

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

1
чи важливо додати його у файл app.module та імпортувати масив? чи ви можете просто імпортувати його в компонент і використовувати його?
Кетрін Р

3
@Katherine R Ви можете використовувати його в будь-якому файлі, він не є кутовим.
Генріх

А тепер, що з моментами плагінів, як миттєві круги?
Greywire

2
Насправді ця відповідь не є кутовим, вона стосується будь-якого проекту Typescript.
Гінріх

Чудово, і як я використовую трубу на шаблон?
vladanPro

98

momentє стороннім глобальним ресурсом. Момент, коли об’єкт живе windowу браузері. Для цього це неправильно importу вашій програмі angular2. Натомість включіть <script>тег у свій html, який завантажить файл moment.js.

Щоб зробити TypeScript щасливим, ви можете додати його

declare var moment: any;

вгорі ваших файлів, де ви використовуєте їх для зупинки помилок компіляції, або ви можете використовувати

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

або використовувати tsd, щоб встановити файл moment.d.ts, який TypeScript може знайти самостійно.

Приклад

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');
}

Просто не забудьте додати тег сценарію у ваш HTML або момент не буде існувати.

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

Завантаження модуля moment

Спочатку вам потрібно буде встановити завантажувач модулів, такий як System.js, щоб завантажити моменти файлів commonjs

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

Потім імпортувати момент у файл, де потрібно

import * as moment from 'moment';

або

import moment = require('moment');

Редагувати:

Існують також варіанти з деякими постачальниками, такими як Webpack або SystemJS builder або Browserify, які не дозволять увімкнути об'єкт вікна. Для отримання додаткової інформації про них, відвідайте їх веб-сайти для отримання інструкцій.


3
Це можливо, але дуже тривалий, тому що вам потрібно мати завантажувач модулів, такий як Systemзавантаження у версії моменту вузла commonjs, і тоді ви зможете посилатися на нього import * as moment from 'moment';або import moment = require('moment');який для всіх намірів і цілей однаковий, але у вас є деякі тонкі відмінності в машинописі.
SnareChops

@SnareChops typings install moment --ambient -- saveне знищує typingsфайл визначення та не створює посилання на ///<reference path="./path/to/moment.d.ts" />? У мене така ж помилка при запускуnpm run tsc
Шон Нортроп,

Це вводить в оману; немає нічого поганого в цьому importмоменті.
Стиглер

2
Ця відповідь неповна, оскільки для керування визначенням моменту вам потрібно використовувати Типи. Крім того, не потрібно нічого імпортувати. Будь ласка, дивіться мою відповідь нижче .
Бернардо Пачеко

8
Ця відповідь вводить в оману, те, що момент є глобальною змінною, не означає, що ви "маєте" завантажувати її як тег сценарію. Ви можете, і вам слід, зв’язати його у файлі постачальника, якщо ви використовуєте якийсь bundler (Webpack). Ви також можете вирішити глобальне завдання, якщо використовуєте веб-пакет і належний завантажувач.
Шломі Ассаф

49

Наступне працювало для мене.

Спочатку встановіть визначення типів на момент.

typings install moment --save

(Примітка: НЕ --ambient )

Потім, щоб подолати відсутність належного експорту:

import * as moment from 'moment';

2
Я повинен був зробити це import moment from "moment";замість цього, щоб він працював.
Етерікс

3
Ця відповідь неповна, оскільки вам не потрібно нічого імпортувати. Будь ласка, дивіться мою відповідь нижче .
Бернардо Пачеко

1
Також кожна ітерація іонної 2 бета / кутової 2 рс здавалася, що приносить новий спосіб імпорту речей, тому вам, можливо, доведеться спробувати декілька цих пропозицій, хоча один момент, коли вони були колись найбільш актуальною відповіддю,
дискіден

import * as moment from 'moment';є ключовим.
німа

У мене не вдається знайти "момент" ("npm") у реєстрі. коли я намагаюся встановити визначення, допоможіть, будь ласка
Себастьян Рохас

28

Я б пішов із наступним:

npm install moment --save

До масиву вашого systemjs.config.jsфайлу mapдодайте:

'moment': 'node_modules/moment'

до packagesмасиву додати:

'moment': { defaultExtension: 'js' }

У своєму компоненті.ts використовуйте: import * as moment from 'moment/moment';

і це все. Ви можете використовувати з класу свого компонента:

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


25

Зараз ми використовуємо модулі,

спробуйте import {MomentModule} from 'angular2-moment/moment.module';

після npm install angular2-moment

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


76
Цього недостатньо, оскільки це встановлює лише труби. Мабуть, ви не можете таким чином працювати з датами «Момент» у своїх модулях.
ntaso

1
хотілося б порадити, як використовувати фільтри angular2-moment у класі компонентів
trickpatty

3
це повинно бути: імпорт {MomentModule} з 'angular2-moment / moment.module';
Яссер

1
Це вже не має бути обраною відповіддю. Подивіться на відповідь @Hinrich. npm install moment --save, npm install @types/moment --save Stackoverflow.com/questions/35166168 / ...
jamesjansson

замість того, щоб встановлювати обгортку, це має бути якimport * as moment from 'moment';
М. Атіф Ріаз

22

Щоб використовувати його в Typescriptпроекті, вам потрібно буде встановити момент:

npm install moment --save

Після установки моменту, ви можете використовувати його в будь-якому .tsфайлі після імпорту:

import * as moment from "moment";


1
Примітка ** @ типів / момент @ 2.13.0: Це визначення типів заглушки для Моменту ( github.com/moment/moment ). Момент надає свої власні визначення типів, тому вам не потрібно встановлювати @ типи / моменти!
Winnemucca

1
Чудово! Ось офіційна довідка: momentjs.com/docs/#/use-it/typescript
Андреа

14

--- Оновлення 01.01.2017

Типи тепер застаріли, і його замінили npm @types . Відтепер для отримання оголошень типу не потрібно буде використовувати будь-які інструменти, крім npm. Щоб використовувати Moment, вам не потрібно буде встановлювати визначення типів через @types оскільки Moment вже надає свої власні визначення типів.

Отже, вона зводиться лише до 3 кроків:

1 - момент встановлення, який включає визначення типів:

npm install moment --save

2 - Додайте тег сценарію у свій HTML-файл:

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

3 - Тепер ви можете просто ним скористатися. Період.

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

--- Оригінальна відповідь

Це можна зробити всього за 3 кроки:

1 - Встановлення визначення моменту - * .d.ts файл:

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

2 - Додайте тег сценарію у свій HTML-файл:

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

3 - Тепер ви можете просто ним скористатися. Період.

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

У мене виникають проблеми з версією типінгу, яка доступна в dt. Він використовує стару версію моменту, в якій немає нових методів, які я хочу використовувати. Якщо я виконую так, як їх рекомендують ( momentjs.com/docs/#/use-it/system-js ), програма компілюється, але не завантажується у браузер. Я майже досягнув глухий кут ...
Фабрикіо

Я не зміг заставити тег сценарію для роботи з кутовим кліпом. Має сенс більше, ніж імпортувати
Winnemucca,

@Bernardo Я намагався виконувати ваші кроки та встановив moment.js. Після цього declare var moment;типізація не працює для мене. Після введення moment().немає інтелігенції. Я думаю, я пропускаю тут кілька кроків.
Shyamal Parikh

Досить впевнений, що це не працює, як веб-пакет знає, щоб включити це до модулів вузлів збірки?
johnny 5

12

Для кутових 7+ (підтримує також 8 та 9) :

1: Встановити момент командою npm install moment --save

2: Не додайте нічого в app.module.ts

3: Просто додайте заяву про імпорт до верхнього componentабо будь-якого іншого файлу, подібного до цього:import * as moment from 'moment';

4: Тепер ви можете використовувати в momentбудь-якому місці свого коду. Так як:

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


Мені довелося імпортувати так: import * as moment_ from 'moment'; const moment = moment_;інакше я отримувавError: Cannot call a namespace ('moment')
Снук

Дуже дивно слухати. moment_- це просто буквальне ім'я. Думаю, це може бути що завгодно ...
Рахмат Алі

1
Тільки майте на увазі, що import * as moment from 'moment';збільште розмір пакету на ~ 500 кб. Існує гарна стаття з описом проблеми з розчином medium.jonasbandi.net / ...
Kosmonaft

9

з CLI

> npm install moment --save

в app.module

import * as moment from 'moment';

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

в складовій

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

таким чином ви імпортуєте момент один раз

ОНОВЛЕННЯ кутова => 5

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

Для мене працює в продажі з aot, а також з універсальним

Мені не подобається використовувати будь-який, але використовуючи момент. Момент, який я отримав

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

Я отримую Parameter 'moment' implicitly has an 'any' typeпомилку.
Азимут

Це працює для вас у режимі prod? Він працював нормально в режимі розробки, але коли я запускаю свою програму в режимі prod, вона не працює. У моєму додатку є також ледачі завантажені модулі (про всяк випадок, коли це має значення). момент закінчується недійсним.
jbgarr

@jbgarr Я спробував у ледачому модулі, як конструктор (@Inject ('момент') приватний момент) {console.log ('дата', момент ()); } без проблем
Whisher

8

У бібліотеці angular2-моменту є труби типу {{myDate | amTimeAgo}} для використання у файлах .html.

До цих самих труб також можна отримати доступ до функцій Typescript у файлі класу компонентів (.ts). Спочатку встановіть бібліотеку згідно інструкцій:

npm install --save angular2-moment

У node_modules / angular2-moment тепер будуть файли ".pipe.d.ts", такі як Calendar.pipe.d.ts , date-format.pipe.d.ts та багато іншого.

Кожен з них містить ім'я функції Typescript для еквівалентної труби, наприклад, DateFormatPipe () є функцією для amDateFormatPipe .

Щоб використовувати DateFormatPipe у своєму проекті, імпортуйте та додайте його до своїх глобальних провайдерів у app.module.ts:

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

Потім у будь-який компонент, де ви хочете використовувати функцію, імпортуйте її зверху, введіть у конструктор і використовуйте:

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

Щоб скористатися будь-якою з функцій, виконайте цей процес. Було б добре, якби був один спосіб отримати доступ до всіх функцій, але жодне з перерахованих вище рішень не працювало для мене.


Це дивовижне спасибі! Скрізь протягом angular2 момент показує, як використовувати його лише для шаблону. Ваш дуже корисний пост показав мені, як використовувати його для маніпулювання значенням, перш ніж я вивести його в шаблон.
Ендрю-молодший Говард

@royappa Я бачу деяких, що використовують модуль Pipes, а деяких, що використовують момент, щоб отримати доступ до нього в Typescript. Я розумію, ви говорите, що можете використовувати версію Pipes в Typescript, але яка шкода може бути при встановленні обох?
Жак

5

Якщо ви все добре додаєте сторонні пакети, я використав бібліотеку angular2-моменту . Установка була досить простою, і вам слід дотримуватися останніх інструкцій з README. Я також встановив типізації в результаті цього.

Працював як шарм для мене і ледь не додав жодного коду, щоб він працював.


5

Не впевнений, чи це все ще проблема для людей, однак ... Використовуючи SystemJS та MomentJS як бібліотеку, це вирішило це для мене

/*
 * 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;

Звідси для мене добре працює.


5

для angular2 RC5 це працювало для мене ...

перший момент встановлення через npm

npm install moment --save

Потім імпортуйте момент у компонент, який ви хочете ним використовувати

import * as moment from 'moment';

нарешті, налаштуйте момент у systemjs.config.js "map" та "пакети"

// 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'}
  };

Будь-яке уявлення про те, що є еквівалентним кроком для вебпакету?
Бхарат Геледа

@BharatGeleda З веб-пакетом нічого не потрібно робити. За допомогою Angular2 та angular-cli я просто повинен був npm встановити та імпортувати його. Мені не потрібні були типізації, оскільки остання версія моменту підтримує typecript.
Станісладрг відновлює Моніку

1
Єдине рішення, яке змусило мене імпортувати ще одну локаль: import 'moment/locale/de.js';Дякую!
iBaff

4

Окрім відповіді SnareChop, мені довелося змінити файл типізації для momentjs.

У moment-node.d.tsI замінено:

export = moment;

з

export default moment;


4

Моя власна версія використання 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);    

}

Спочатку імпортується як _moment, потім оголошується momentзмінною типу _moment.Momentз початковим значенням _moment().

Звичайний імпорт моменту не дасть вам будь-якого автоматичного завершення, але якщо ви оголосите момент із Momentінтерфейсом типу з _momentпростору імен з 'moment'пакета, ініціалізованого з викликаним простором імен_moment() дає вам автоматичне завершення api.

Я думаю, що це найбільш кутовий спосіб використання моменту без використання @types typingsабо кутових провайдерів, якщо ви шукаєте автоматичне доповнення для бібліотек vanilla javascript на зразок моменту.


Встановлення типів дозволить отримати доступ до автозаповнення:npm install @types/moment --save
jamesjansson

3

Спробуйте додати "allowSyntheticDefaultImports": trueдо свого tsconfig.json.

Що робить прапор?

Це в основному говорить компілятору TypeScript, що нормально використовувати оператор імпорту ES6, тобто

import * as moment from 'moment/moment';

на модулі CommonJS типу Moment.js, який не оголошує експорт за замовчуванням. Прапор впливає лише на перевірку типу, а не на створений код.

Це необхідно, якщо ви використовуєте SystemJS в якості завантажувача модулів. Прапор буде автоматично увімкнено, якщо ви скажете своєму компілятору TS, що ви використовуєте SystemJS:

"module": "system"

Це також видалить будь-які помилки, видані IDE, якщо вони налаштовані для використання tsconfig.json.


2

для angular2 з systemjs і jspm потрібно було зробити:

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

Для користувачів ANGULAR CLI

Використання зовнішніх бібліотек знаходиться в документації тут:

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

Просто встановіть свою бібліотеку через

npm встановити lib-name --save

і імпортувати його у свій код. Якщо бібліотека не включає типізації, ви можете встановити їх за допомогою:

npm встановити lib-name --save

npm встановити @ types / lib-name --save-dev

Потім відкрийте src / tsconfig.app.json і додайте його до масиву типів:

"types": ["lib-name"]

Якщо бібліотека, в яку ви додали типізацію, використовуватиметься лише для ваших тестів e2e, замість цього використовуйте e2e / tsconfig.e2e.json. Те саме стосується одиничних тестів і src / tsconfig.spec.json.

Якщо в бібліотеці немає типізацій, доступних для @ type /, ви все одно можете використовувати її, додавши для неї вручну:

Спочатку створіть файл typing.d.ts у вашому src / папці.

Цей файл буде автоматично включено як глобальне визначення типу. Потім у src / typings.d.ts додайте такий код:

оголосити модуль 'typeless-package';

Нарешті, в компонент або файл, який використовує бібліотеку, додайте наступний код:

імпортувати * як typelessPackage з 'typeless-package'; typelessPackage.method ();

Зроблено. Примітка. Можливо, вам знадобиться або буде корисно визначити більше типів для бібліотеки, яку ви намагаєтеся використовувати.


Ознайомтеся з цією статтею, якщо вам потрібні покрокові інструкції. medium.com/@jek.bao.choo/…
wag0325

1

Я дотримувався поради, щоб дозволити дозволити importSportsteDefaultImports (оскільки експорт з моменту не використовується для мене), використовуючи System. Потім я дотримувався чиєїсь поради щодо використання:

import moment from 'moment';

З моментом відображення в моєму config.js config. Інші заяви про імпорт чомусь не спрацюють


Це остання відповідь зараз, але єдина, яка працює!
TJL

1

Для мене працювало наступне:

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

Вузол моменту не існує в сховищі типінгу. Вам потрібно переадресувати на Визначально введене, щоб змусити його працювати за допомогою префікса dt.


1

Що з системою, що я робив, всередині мого systemjs.config я додав карту для moment

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

І тоді ви можете легко імпортувати, momentпросто роблячи

import * as moment from 'moment'

1

Я знаю, що це стара нитка, але для мене найпростішим рішенням, яке насправді працювало, було:

  1. Встановіть її спочатку npm install moment --save
  2. У моїх компонентах, які вимагають його від node_modules, і використовувати його:
const moment = require('../../../node_modules/moment/moment.js');

@Component({...})
export class MyComponent {
   ...
   ngOnInit() {
       this.now = moment().format();
   }
   ...
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.