Как использовать библиотеку moment.js в приложении 2 с машинописным текстом?

164

Я попытался использовать его с привязками typescript:

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 и использую импорт, я получаю ОШИБКУ при компиляции в ... / typings / browser / ambient / moment / moment.d.ts (9,21): ошибка TS2503: Не удается найти пространство имен 'moment' , И если я не устанавливаю наборы и использую require, я получаю Uncaught TypeError: moment.format не является функцией
Показать ещё 3 комментария
Теги:
angular

23 ответа

345
Лучший ответ

Обновление апреля 2017 года:

Начиная с версии 2.13.0, Moment содержит файл определения typescript. 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");
  • 34
    Я не знаю, почему это не принятый ответ на самом деле.
  • 1
    важно ли добавить его в файл app.module и импортировать массив? или вы можете просто импортировать его в компонент и использовать его?
Показать ещё 9 комментариев
92

moment является сторонним глобальным ресурсом. Объект момента живет в window в браузере. Поэтому это не соответствует import его в приложении angular2. Вместо этого добавьте тег <script> в ваш html, который загрузит файл moment.js.

Чтобы сделать TypeScript счастливым, вы можете добавить

declare var moment: any;

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

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

или используйте tsd для установки файла момента .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');
}

Просто добавьте тег script в свой 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');

EDIT:

Существуют также варианты с некоторыми связями, такими как Webpack или SystemJS builder или Browserify, которые сохранят момент объекта окна. Для получения дополнительной информации о них, пожалуйста, посетите их соответствующие веб-сайты для ознакомления.

  • 3
    Это возможно, но это очень долго, так как вам потребуется иметь загрузчик модулей, такой как System load, в версии момента commonjs для узла, а затем вы сможете ссылаться на него с помощью import * as moment from 'moment'; или import moment = require('moment'); которые для всех намерений и целей идентичны, но имеют некоторые тонкие различия в машинописи.
  • 0
    Момент typings install moment --ambient -- save наборов typings install moment --ambient -- save не typings опускают файл определения и создают ссылку на ///<reference path="./path/to/moment.d.ts" /> ? У меня такая же ошибка при запуске npm run tsc
Показать ещё 6 комментариев
46

Следующие работали для меня.

Сначала установите определения типов для момента.

typings install moment --save

(Примечание: NOT --ambient)

Затем, чтобы обойти отсутствие надлежащего экспорта:

import * as moment from 'moment';
  • 2
    Я должен был сделать import moment from "moment"; вместо этого, чтобы заставить это работать.
  • 5
    import { Moment } from 'moment'; работал на меня.
Показать ещё 4 комментария
28

Я бы сказал следующее:

npm install moment --save

В массив systemjs.config.js file map добавьте:

'moment': 'node_modules/moment'

to packages array add:

'moment': { defaultExtension: 'js' }

В вашем приложении component.ts: import * as moment from 'moment/moment';

и что он. Вы можете использовать его из класса компонентов:

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

24

Сейчас мы используем модули,

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

после npm install angular2-moment

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

  • 76
    Этого недостаточно, потому что это только устанавливает трубы. Очевидно, вы не можете работать с датами Момента в ваших модулях таким образом.
  • 1
    хотелось бы несколько советов о том, как использовать Angular2-моментные фильтры в классе компонентов
Показать ещё 4 комментария
20

Чтобы использовать его в проекте Typescript, вам нужно установить момент:

npm install moment --save

После установки момента его можно использовать в любом файле .ts после его импорта:

import * as moment from "moment";

  • 1
    Примечание ** @ types / moment @ 2.13.0: это определение типов заглушки для Moment ( github.com/moment/moment ). Moment предоставляет свои собственные определения типов, поэтому вам не нужно устанавливать @ types / moment!
  • 1
    Большой! Вот официальная ссылка: momentjs.com/docs/#/use-it/typescript
14

--- Обновление 11/01/2017

Параметры теперь устарели и заменены на npm @types. С этого момента получение объявлений типа не потребует инструментов, кроме npm. Чтобы использовать Moment, вам не нужно устанавливать определения типов с помощью @types, поскольку Moment уже предоставляет свои собственные определения типов.

Итак, он сводится к 3 шагам:

1 - Установить момент, который включает определения типов:

npm install moment --save

2 - Добавьте тег script в свой 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 - Добавьте тег script в свой HTML файл:

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

3 - Теперь вы можете просто использовать его. Период.

today: string = moment().format('D MMM YYYY');
  • 0
    У меня возникли проблемы с версией для печати, которая доступна на DT. Он использует старую версию момента, в которой нет новых методов, которые я хочу использовать. Если я делаю так, как они рекомендуют ( momentjs.com/docs/#/use-it/system-js ), приложение компилируется, но не загружается в браузер. Я почти зашел в тупик ...
  • 0
    Я не смог заставить тег script работать с angular cli. Имеет больше смысла, чем импорт, хотя
Показать ещё 3 комментария
9

с ng CLI

> npm install moment --save

в app.module

import * as moment from 'moment';

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

в компоненте

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

таким образом вы сразу импортируете момент

ОБНОВЛЕНИЕ Angular = > 5

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

Для меня работает в prod с aot а также с универсальным

Мне не нравится использовать любой, но используя момент. Момент Я получил

Error   Typescript  Type 'typeof moment' is not assignable to type 'Moment'. Property 'format' is missing in type 'typeof moment'.
  • 0
    Я получаю Parameter 'moment' implicitly has an 'any' type ошибку Parameter 'moment' implicitly has an 'any' type .
  • 0
    Это работает для вас в режиме Prod? Он работал нормально в режиме разработки, но когда я запускаю свое приложение в режиме Prod, это не удается. Мое приложение имеет лениво загруженные модули тоже (на всякий случай, если это имеет значение). момент становится нулевым.
Показать ещё 2 комментария
8

Библиотека angular2 -moment имеет такие каналы, как {{myDate | amTimeAgo}} для использования в файлах .html.

Те же самые каналы можно также получить в виде Typescript функций в файле класса компонента (.ts). Сначала установите библиотеку в соответствии с инструкциями:

npm install --save angular2-moment

В node_modules/angular2 -момент теперь будут ".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');
}

Чтобы использовать любую из функций, следуйте этому процессу. Было бы неплохо, если бы был один способ получить доступ ко всем функциям, но ни один из вышеперечисленных решений не работал у меня.

  • 0
    Это потрясающе, спасибо! Везде для angular2 момент показывает вам, как использовать его только на шаблоне. Ваш очень полезный пост показал мне, как использовать его для манипулирования значением, прежде чем я выведу его в шаблон.
  • 0
    @royappa Я вижу, что некоторые используют модуль Pipes, а некоторые используют только мгновение для доступа к нему в Typescript. Я понимаю, что вы говорите, что можете использовать версию Pipes в Typescript, но какой вред это даст при установке обоих?
5

для angular2 RC5 это сработало для меня...

первый момент установки через npm

npm install moment --save

Затем импортируйте момент в компоненте, который вы хотите использовать

import * as moment from 'moment';

окончательно настройте момент в systemjs.config.js "map" и "packages"

// 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'}
  };
  • 0
    Любая идея о том, что эквивалентный шаг для веб-пакета?
  • 0
    @BharatGeleda Нет необходимости делать что-либо с веб-пакетом. Используя Angular2 и angular-cli, мне просто нужно было установить и импортировать npm. Мне не нужно было печатать, так как последняя версия момента поддерживает машинопись.
Показать ещё 1 комментарий
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-moment. Установка была довольно простой, и вы должны следовать последним инструкциям README. Я также установил typings в результате этого.

Работал как прелесть для меня, и едва добавил код, чтобы заставить его работать.

4

Moment.js теперь поддерживает TypeScript в v2.14.1.

Смотрите: https://github.com/moment/moment/pull/3280

3

Попробуйте добавить "allowSyntheticDefaultImports": true к вашему tsconfig.json.

Что делает флаг?

Это в основном говорит компилятору TypeScript, что в нем можно использовать инструкцию импорта ES6, т.е. е.

import * as moment from 'moment/moment';

в модуле CommonJS, таком как Moment.js, который не объявляет экспорт по умолчанию. Флаг влияет только на проверку типов, а не на сгенерированный код.

Это необходимо, если вы используете SystemJS в качестве загрузчика вашего модуля. Флаг будет автоматически включен, если вы сообщите своему TS-компилятору, что вы используете SystemJS:

"module": "system"

Это также приведет к удалению любых ошибок, создаваемых IDE, если они настроены на использование tsconfig.json.

3

В дополнение к ответу на SnareChop мне пришлось изменить файл типизации для momentjs.

В moment-node.d.ts я заменил:

export = moment;

с

export default moment;
2

Для ANGULAR пользователей CLI

Использование внешних библиотек содержится в документации:

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

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

npm install lib-name --save

и импортировать его в свой код. Если библиотека не содержит титров, вы можете установить их, используя:

npm install lib-name --save

     

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

Затем откройте src/tsconfig.app.json и добавьте его в массив типов:

"types": [ "lib-name" ]

Если библиотека, к которой вы добавили типизацию, используется только для вашего e2e тестов, вместо этого используйте e2e/tsconfig.e2e.json. То же самое касается модульных тестов и src/tsconfig.spec.json.

Если библиотека не имеет типов, доступных в @types/, вы можете по-прежнему используйте его, вручную добавив для него пиктограммы:

Сначала создайте файл typings.d.ts в папке src/.

Этот файл будет автоматически включен как определение глобального типа. Затем в src/typings.d.ts добавьте следующий код:

объявить модуль 'typeless-package';

Наконец, в компоненте или файле, который использует библиотеку, добавьте следующий код:

import * как noelessPackage из 'typeless-package';   typelessPackage.method();

Готово. Примечание: вам может понадобиться или найти полезное для определения большего числа типов для библиотеку, которую вы пытаетесь использовать.

  • 0
    Закажите эту статью, если вам нужны пошаговые инструкции. medium.com/@jek.bao.choo/...
2

для angular2 с системой js и 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();
1

Моя собственная версия использования Moment in Angular

npm я 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 или угловых провайдеров, если вы ищете автоматическое завершение для ванильных библиотек javascript, таких как момент.

  • 0
    Установка типов позволит вам получить доступ к автозаполнению: npm install @types/moment --save
1

Я знаю, что это старый поток, но для меня самое простое решение, которое на самом деле работало:

  • Установка сначала npm install moment --save
  • В моих компонентах, требующих его от node_modules, и используйте его:
const moment = require('../../../node_modules/moment/moment.js');

@Component({...})
export class MyComponent {
   ...
   ngOnInit() {
       this.now = moment().format();
   }
   ...
}
1

С systemjs, что я сделал, внутри моей systemjs.config я добавил карту для moment

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

И тогда вы можете легко импортировать moment, просто выполняя

import * as moment from 'moment'
1

Следующие работали для меня:

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

Момент-node не существует в репозитории типизирования. Вам нужно перенаправить на определенно типизированный, чтобы заставить его работать с помощью префикса dt.

0
import { MAT_MOMENT_DATE_FORMATS, MomentDateAdapter } from '@angular/material-moment-adapter';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
import * as moment from 'moment';


@Component({
  selector: 'app-user-details',
  templateUrl: './user-details.component.html',
  styleUrls: ['./user-details.component.scss'],
  providers: [
    { provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
    { provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },
    // {provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
  ],
})
export class UserDetailsComponent implements OnInit {

  userDetailsFormGroup = this.fb.group({
    firstName: [''],
    lastName: [''],
    username: [''],
    address: ['', Validators.required],
    dob: [moment(), Validators.required],
    gender: ['', Validators.required],
    contactNumber: ['', Validators.required],
  });



   updateUserProfile() {

   const dobDate = this.userDetailsFormGroup.controls.dob.value;
     const momentDOB1 = dobDate.format('MM/DD/YYYY');

       const body = {
      'firstName': this.userDetailsFormGroup.controls.firstName.value,
      'lastName': this.userDetailsFormGroup.controls.lastName.value,
      'address': this.userDetailsFormGroup.controls.address.value,
      'dob': momentDOB1,
      'gender': this.userDetailsFormGroup.controls.gender.value,
      'contactNumber': this.userDetailsFormGroup.controls.contactNumber.value

    };


    // call http method here
   }


   getUserProfileData(){

   //get http 
    this.http.get<any>(AppSettings.BASE_URL + '/v1/userProfile/getMyProfile').pipe()
      .subscribe(
      data => {
       const dateDob = moment(data.dob, 'MM/DD/YYYY');
         console.log('getting date format :::');
          console.log(dateDob.toISOString());
       this.userDetailsFormGroup.controls.dob.setValue(dateDob);
      }
      );
}
0

Я посоветовал разрешить allowSyntheticDefaultImports (так как для меня нет экспорта с момента использования), используя System. Затем я последовал за советом:

import moment from 'moment';

С моментом, отображаемым в моей конфигурации system.js. Другие операторы импорта не будут работать для меня по какой-либо причине

Ещё вопросы

Сообщество Overcoder
Наверх
Меню