Angular - Gunakan pipa dalam servis dan komponen

331

Di AngularJS, saya dapat menggunakan filter (pipa) di dalam layanan dan pengontrol menggunakan sintaksis yang mirip dengan ini:

$filter('date')(myDate, 'yyyy-MM-dd');

Apakah mungkin menggunakan pipa dalam layanan / komponen seperti ini di Angular?

Sesuai dengan POSIX
sumber
1
untuk Angular 8 Periksa tutorial ini tentang Built In dan Custom Pipes freakyjolly.com/angular-8-pipes-all-type-of-pipes-with-examples
Code Spy

Jawaban:

660

Seperti biasa di Angular, Anda dapat mengandalkan injeksi ketergantungan:

import { DatePipe } from '@angular/common';

class MyService {

  constructor(private datePipe: DatePipe) {}

  transformDate(date) {
    return this.datePipe.transform(date, 'yyyy-MM-dd');
  }
}

Tambahkan DatePipeke daftar penyedia Anda di modul Anda; jika Anda lupa melakukan ini, Anda akan mendapatkan kesalahan no provider for DatePipe:

providers: [DatePipe,...]

Perbarui Angular 6 : Angular 6 sekarang menawarkan hampir semua fungsi pemformatan yang digunakan oleh pipa secara publik. Misalnya, Anda sekarang dapat menggunakan formatDatefungsi secara langsung.

import { formatDate } from '@angular/common';

class MyService {

  constructor(@Inject(LOCALE_ID) private locale: string) {}

  transformDate(date) {
    return formatDate(date, 'yyyy-MM-dd', this.locale);
  }
}

Sebelum Angular 5 : Berhati-hatilah karena DatePipeia mengandalkan API Intl hingga versi 5, yang tidak didukung oleh semua browser (periksa tabel kompatibilitasnya ).

Jika Anda menggunakan versi Angular yang lebih lama, Anda harus menambahkan Intlpolyfill ke proyek Anda untuk menghindari masalah. Lihat pertanyaan terkait ini untuk jawaban yang lebih terperinci.

cexbrayat
sumber
Apa hasil dari menggunakan DatePipe di browser yang tidak mendukung Intl? Apakah ada jenis shim / ployfill yang tersedia untuk mengatasi kurangnya dukungan?
Sesuai dengan POSIX
Sayangnya itu akan menimbulkan kesalahan dan merusak aplikasi Anda sekarang. Ada masalah yang dibuka pada pelacak Github, tetapi sepertinya saat ini tidak ada polyfill yang baik ...
cexbrayat
4
Tampaknya ini tidak berfungsi untuk pipa kustom yang menggunakan injeksi ketergantungan sendiri di konstruktornya. Atau saya salah?
Murray Smith
1
@JayChase dalam "angular2 / common".
valter.santos.matos
5
@JayChase mengimpor dan menambahkan bagian penyedia komponen: `` `import {DatePipe} dari '@ angular / common'; @Component ({... provider: [..., DatePipe]}) `` `
alx lark
74

Jawaban ini sekarang sudah usang

merekomendasikan menggunakan pendekatan DI dari jawaban lain alih-alih pendekatan ini

Jawaban asli:

Anda harus dapat menggunakan kelas secara langsung

new DatePipe().transform(myDate, 'yyyy-MM-dd');

Misalnya

var raw = new Date(2015, 1, 12);
var formatted = new DatePipe().transform(raw, 'yyyy-MM-dd');
expect(formatted).toEqual('2015-02-12');
SnareChops
sumber
2
Saat menggunakan Datekonstruktor javascript , bulan 0didasarkan. Begitu 0juga Januari dan 1Februari. Hilang dikoreksiy
SnareChops
24
Jika itu membantu orang lain, pipa tanggal diimpor dari 'angular2 / common'.
POSIX-compliant
1
Cuplikan kode tidak dapat dikompilasi .... error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'string'. onlinevar formatted = new DatePipe().transform(raw, ['yyyy-MM-dd']);
Paul Gorbas
10
Sekarang dirilis Angular v2.0.0, dan Anda dapat menyuntikkan pipa ini. Pertama, tambahkan ke NgModule:, @NgModule({ providers:[DatePipe] })lalu di kelas Anda, impor dan suntikkan constructor( private datePipe: DatePipe ){}
ktretyak
2
Sementara itu, Angular2 DatePipe mengharapkan Locale_ID sebagai argumen konstruktor. Jadi jika Anda mencoba untuk menggunakannya secara langsung, Anda harus menyediakan perbaikan Locale_ID dan karenanya tidak akan mengambil aplikasi Locale_ID lagi. Itu sebabnya saya TIDAK akan merekomendasikan untuk pergi ke sana.
E. Hein
17

Ya, itu mungkin dengan menggunakan pipa kustom sederhana. Keuntungan menggunakan pipa kustom adalah jika kita perlu memperbarui format tanggal di masa depan, kita dapat pergi dan memperbarui satu file.

import { Pipe, PipeTransform } from '@angular/core';
import { DatePipe } from '@angular/common';

@Pipe({
    name: 'dateFormatPipe',
})
export class dateFormatPipe implements PipeTransform {
    transform(value: string) {
       var datePipe = new DatePipe("en-US");
        value = datePipe.transform(value, 'MMM-dd-yyyy');
        return value;
    }
}

{{currentDate | dateFormatPipe }}

Anda selalu dapat menggunakan pipa ini di mana saja, komponen, layanan dll

Sebagai contoh

export class AppComponent {
  currentDate : any;
  newDate : any;
  constructor(){
    this.currentDate = new Date().getTime();
    let dateFormatPipeFilter = new dateFormatPipe();
    this.newDate = dateFormatPipeFilter.transform(this.currentDate);
    console.log(this.newDate);
}

Jangan lupa untuk mengimpor dependensi.

import { Component } from '@angular/core';
import {dateFormatPipe} from './pipes'

Contoh Pipa Kustom dan info lainnya

Prashobh
sumber
1
Ini tidak menjawab pertanyaan tentang bagaimana menggunakan pipa dalam komponen atau layanan.
Sesuai POSIX
2
Saya akan menghapus downvote saya jika Anda akan memperbarui jawaban Anda untuk tidak menyertakan informasi tentang cara membuat pipa. Pertanyaannya tidak ada hubungannya dengan cara membuatnya.
Sesuai POSIX
2
@ POSIX-compliant Seperti yang saya sebutkan dalam jawaban saya itu dapat digunakan kembali dan diperbarui dengan sangat mudah dengan menggunakan pipa kustom. Mungkin membantu penuh untuk orang lain. Suara adalah nomor dua.
Prashobh
1
Itu poin yang adil meskipun saya masih berpikir masuk akal untuk setidaknya memiliki bagian yang menjawab pertanyaan spesifik ini terlebih dahulu. Menghapus suara. Terima kasih atas jawabannya dan membalas.
POSIX-compliant
1
Mengapa Anda mengubah kode "en-US"? Haruskah Anda tidak menyuntikkan entah bagaimana?
Gherman
15

Jawaban lain tidak bekerja di sudut 5?

Saya mendapat kesalahan karena DatePipe bukan penyedia, jadi tidak bisa disuntikkan. Salah satu solusinya adalah dengan menempatkannya sebagai penyedia dalam modul aplikasi Anda, tetapi solusi pilihan saya adalah dengan instantiate.

Instantiate itu di mana diperlukan:

Saya melihat kode sumber DatePipe untuk melihat bagaimana ia mendapatkan lokal: https://github.com/angular/angular/blob/5.2.5/packages/common/src/pipes/date_pipe.ts#L15-L174

Saya ingin menggunakannya di dalam pipa, jadi contoh saya adalah di dalam pipa lain:

import { Pipe, PipeTransform, Inject, LOCALE_ID } from '@angular/core';
import { DatePipe } from '@angular/common';

@Pipe({
    name: 'when',
})
export class WhenPipe implements PipeTransform {
    static today = new Date((new Date).toDateString().split(' ').slice(1).join(' '));
    datePipe: DatePipe;

    constructor(@Inject(LOCALE_ID) private locale: string) {
        this.datePipe = new DatePipe(locale);
    }
    transform(value: string | Date): string {
        if (typeof(value) === 'string')
            value = new Date(value);

        return this.datePipe.transform(value, value < WhenPipe.today ? 'MMM d': 'shortTime')
    }
}

Kuncinya di sini adalah mengimpor Suntikan, dan LOCALE_ID dari inti sudut, dan kemudian menyuntikkannya sehingga Anda dapat memberikannya ke DatePipe untuk membuat instantiate dengan benar.

Jadikan DatePipe sebagai penyedia

Di modul aplikasi Anda, Anda juga bisa menambahkan DatePipe ke array penyedia Anda seperti ini:

import { DatePipe } from '@angular/common';

@NgModule({
    providers: [
        DatePipe
    ]
})

Sekarang Anda bisa menyuntikkannya ke konstruktor di mana diperlukan (seperti dalam jawaban cexbrayat).

Ringkasan:

Salah satu solusi yang berhasil, saya tidak tahu yang mana sudut akan dianggap paling "benar" tetapi saya memilih untuk instantiate secara manual karena sudut tidak menyediakan datepipe sebagai penyedia itu sendiri.

csga5000
sumber
3
Anda dapat membuatnya juga penyedia per komponen
Jimmy Kane
Terima kasih, jawaban Anda adalah yang paling lengkap. Saya mencari beberapa sumber pada perbedaan antara instantiating pipa dengan yang baru atau ketergantungan menyuntikkannya langsung dan menambahkannya ke penyedia dan tidak dapat menemukan apa pun. Saya lebih suka pendekatan 2, karena ketika Anda newmenaiki pipa, Anda masih harus DI lokal. Saya menemukan seluruh @Inject(LOCALE_ID) private locale: stringsintaksnya rumit.
codeepic
@ codeepic Saya mungkin tidak akan mengatakan ada perbedaan besar sebenarnya. Jika Anda bertanya kepada saya, sudut mungkin harus membuatnya menjadi penyedia.
csga5000
9

Jika Anda tidak ingin melakukan 'myPipe baru ()' karena Anda menyuntikkan dependensi ke pipa, Anda dapat menyuntikkan komponen seperti penyedia dan digunakan tanpa yang baru.

Contoh:

// In your component...

import { Component, OnInit } from '@angular/core';
import { myPipe} from './pipes';

@Component({
  selector: 'my-component',
  template: '{{ data }}',
  providers: [ myPipe ]
})
export class MyComponent() implements OnInit {
  data = 'some data';
  constructor(private myPipe: myPipe) {}

  ngOnInit() {
    this.data = this.myPipe.transform(this.data);
  }
}
andy
sumber
9

Jika Anda ingin menggunakan pipa kustom di komponen Anda, Anda dapat menambahkan

@Injectable({
  providedIn: 'root'
})

penjelasan untuk pipa kustom Anda. Kemudian, Anda dapat menggunakannya sebagai layanan

srt
sumber
apakah baik untuk providedIn: 'root'berada di dalam pipa kami atau disediakan dalam modul lokal di mana pipa digunakan?
Daniel.V
1
Itu tergantung di mana Anda menggunakan pipa. Jika Anda menggunakan pipa hanya dalam satu modul maka Anda dapat memilih opsi kedua. Tetapi jika Anda menggunakan pipa di beberapa modul di aplikasi Anda, Anda harus memilih opsi pertama yang disediakanIn: 'root'
srt
5

Anda dapat menggunakan formatDate () untuk memformat tanggal di layanan atau komponen ts. sintaksis:-

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

impor formatDate () dari modul umum seperti ini,

import { formatDate } from '@angular/common';

dan gunakan saja di kelas seperti ini,

formatDate(new Date(), 'MMMM dd yyyy', 'en');

Anda juga dapat menggunakan opsi format yang disediakan oleh sudut seperti ini,

formatDate(new Date(), 'shortDate', 'en');

Anda dapat melihat semua opsi format yang telah ditentukan di sini,

https://angular.io/api/common/DatePipe

Sksaif Uddin
sumber