'' Borusu açısal2 özel boru bulunamadı


105

Bu hatayı düzeltemiyorum. Bir arama çubuğum ve bir ngFor'm var. Şunun gibi özel bir boru kullanarak diziyi filtrelemeye çalışıyorum:

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

import { User } from '../user/user';

@Pipe({
  name: 'usersPipe',
  pure: false
})
export class UsersPipe implements PipeTransform {
  transform(users: User [], searchTerm: string) {
    return users.filter(user => user.name.indexOf(searchTerm) !== -1);
  }
}

Kullanım:

<input [(ngModel)]="searchTerm" type="text" placeholder="Search users">

<div *ngFor="let user of (users | usersPipe:searchTerm)">
...
</div>

Hata:

zone.js:478 Unhandled Promise rejection: Template parse errors:
The pipe 'usersPipe' could not be found ("
<div class="row">
    <div  
    [ERROR ->]*ngFor="let user of (user | usersPipe:searchTerm)">

Açısal versiyonlar:

"@angular/common": "2.0.0-rc.5",
"@angular/compiler": "2.0.0-rc.5",
"@angular/core": "2.0.0-rc.5",
"@angular/platform-browser": "2.0.0-rc.5",
"@angular/platform-browser-dynamic": "2.0.0-rc.5",
"@angular/router": "3.0.0-rc.1",
"@angular/forms": "0.3.0",
"@angular/http": "2.0.0-rc.5",
"es6-shim": "^0.35.0",
"reflect-metadata": "0.1.3",
"rxjs": "5.0.0-beta.6",
"systemjs": "0.19.26",
"bootstrap": "^3.3.6",
"zone.js": "^0.6.12"

1
Bileşen Borularına dahil ettiniz mi?
Harry Ninh

Sebebinin bu olduğunu anladım. Nasıl özel boru açısal örneği asla yapar: angular.io/resources/live-examples/pipes/ts/plnkr.html
Sumama Waheed

Bunu küresel boru olarak tanımladılar. Birçok yerde kullanıyorsanız ve her bir ek açıklamada tanımlamak istemiyorsanız, özel borunuza da aynısını yapabilirsiniz.
Harry Ninh

@SumamaWaheed Dokümanların bir noktasında orada olduğundan oldukça eminim, ama doğru söylüyorsunuz şimdi dokümanlar bundan bahsetmeyin / göstermeyin.
Michelangelo

Yanıtlar:


144

Bir "çapraz modül" sorunuyla karşılaşmadığınızdan emin olun

Boruyu kullanan bileşen boru bileşenini "global" olarak bildiren modüle ait değilse boru bulunmaz ve bu hata mesajını alırsınız.

Benim durumumda boruyu ayrı bir modülde beyan ettim ve bu boru modülünü boruyu kullanan bileşenlere sahip başka herhangi bir modüle ithal ettim.

Boruyu kullandığınız bileşenin,

Boru Modülü

 import { NgModule }      from '@angular/core';
 import { myDateFormat }          from '../directives/myDateFormat';

 @NgModule({
     imports:        [],
     declarations:   [myDateFormat],
     exports:        [myDateFormat],
 })

 export class PipeModule {

   static forRoot() {
      return {
          ngModule: PipeModule,
          providers: [],
      };
   }
 } 

Başka bir modülde kullanım (örn. App.module)

  // Import APPLICATION MODULES
  ...
  import { PipeModule }    from './tools/PipeModule';

  @NgModule({
     imports: [
    ...
    , PipeModule.forRoot()
    ....
  ],

6
Bu çözüm benim için çalışan tek çözümdü. Bir modüle sahip olmak için boruların gerekli olduğu ortaya çıktı
AJ Zane

Bunu, Ng 2.8'de borum bulunamadı hatasını kısmen çözmek için ben de buldum. şablonda.
CNSKnight

Bu gerçekten benim için işe yarayan tek çözüm! Tüm paylaşılan modül olayını denedim, ancak bu çözüm harika çalıştı. Teşekkür ederim @Karl!
lulu88

bunu bileşen testimizde nasıl test ederiz,
apoorva

2
Teşekkürler! Sorunum, ihracatın sadece modüller için olduğunu düşünerek "dışa aktarım: [myPipe]" ı kaçırmamdı!
Rafique Mohammed

55

Borunuzu modül bildirimine eklemeniz gerekir:

declarations: [ UsersPipe ],
providers: [UsersPipe]

5
Sadece bir not, başlangıçta boruyu sağlayıcılara ekledim. Bunun, modül dosyasında hem bildirimlere hem de sağlayıcılara dahil edilmesi gerekir.
Greg A

Önerinize uyana kadar mücadele ediyordum. sadece anlamak için yaklaşık 4 saat harcadım. Önerin için teşekkürler.
user1501382

5
Bu neden belgelenmedi? Belgeler şunu belirtir You must include your pipe in the declarations array of the AppModule.: angular.io/guide/pipes . Her neyse, cevabınız da sorunumu çözüyor.
Martijn

Teşekkürler Yuvals. Bir ayrıntı ekliyorum: boruya ihtiyaç duyduğunuz modülün beyanı.
Vinicios Torres

5
exports: [UsersPipe]Modülün diğer modüller tarafından içe aktarılıp aktarılmayacağını da eklemeyi unutmayın .
Precastic

18

Ionic için @Karl'ın bahsettiği gibi birden fazla sorunla karşılaşabilirsiniz. İyonik tembel yüklenen sayfalar için kusursuz çalışan çözüm şudur:

  1. Şu dosyalarla borular dizini oluşturun: borular.ts ve borular.module.ts

// pipe.ts içeriği (içinde birden fazla boru olabilir, sadece şunu unutmayın:

use @Pipe function before each class)
import { PipeTransform, Pipe } from "@angular/core";
@Pipe({ name: "toArray" })
export class toArrayPipe implements PipeTransform {
  transform(value, args: string[]): any {
    if (!value) return value;
    let keys = [];
    for (let key in value) {
      keys.push({ key: key, value: value[key] });
    }
    return keys;
  }
}

// borular.module.ts içeriği

import { NgModule } from "@angular/core";
import { IonicModule } from "ionic-angular";
import { toArrayPipe } from "./pipes";

@NgModule({
  declarations: [toArrayPipe],
  imports: [IonicModule],
  exports: [toArrayPipe]
})
export class PipesModule {}
  1. PipesModule'ü app.module ve @NgModule içe aktarmalar bölümüne dahil edin

    import { PipesModule } from "../pipes/pipes.module"; @NgModule({ imports: [ PipesModule ] });

  2. Özel kanalları kullanmak istediğiniz her .module.ts dosyanıza PipesModule ekleyin. İthalatlar bölümüne eklemeyi unutmayın. // Misal. dosya: sayfalar / özel-sayfam / özel-sayfam.module.ts

    import { PipesModule } from "../../pipes/pipes.module"; @NgModule({ imports: [ PipesModule ] })

  3. Bu kadar. Artık şablonunuzda özel borunuzu kullanabilirsiniz. Örn.

<div *ngFor="let prop of myObject | toArray">{{ prop.key }}</div>


Bu iyonik için bir cankurtarandı, teşekkürler. Çünkü "iyonik boru oluştur ....", borular.module.ts oluşturmak gibi gereken tüm adımları oluşturmaz. Yaklaşımınız mükemmel çalıştı. İonic v4 için içe aktarma yollarında bazı küçük değişikliklerin yapılması gerektiğini unutmayın.
royappa

1
App.module.ts içindeki içe aktarmalara ihtiyacınız olmadığını fark ettim, bu nedenle bu adım atlanabilir. Bunun nedeni, "paylaşılan modülün" her halükarda ihtiyaç duyulan her bir modüle aktarılıyor olması olabilir. App.module içe aktarımının global olarak çalışması iyi olurdu, ancak denedim ve olmadı.
royappa

Hala bununla karşı karşıyayım: CONSOLE ERROR dosyası: node_modules/@angular/core/fesm5/core.js: 4002: 0 HATA Hatası: Yakalanmamış (sözde): NullInjectorError: StaticInjectorError (AppModule) [ToHtmlPipe -> DomSanitizer]: StaticInjectorError (Platform: core) [ToHtmlPipe -> DomSanitizer]: NullInjectorError: DomSanitizer için sağlayıcı yok!
mircobabini

12

Yukarıdaki "çapraz modül" cevabını durumuma çok yardımcı buldum, ancak dikkate alınması gereken başka bir kırışıklık olduğu için bu konuyu genişletmek isterim. Bir alt modülünüz varsa, testimde üst modüldeki boruları da göremez. Bu nedenle ayrıca kendi ayrı modüllerine boru koymanız gerekebilir.

Alt modülde görünmeyen boruları ele almak için attığım adımların bir özeti:

  1. (Üst) SharedModule'dan boruları alın ve PipeModule'a koyun
  2. SharedModule'da, PipeModule'ü içe aktarın ve dışa aktarın ( PipModule'a otomatik olarak erişim sağlamak için SharedModule'a bağlı diğer uygulama bölümleri için)
  3. Sub-SharedModule için, PipeModule'ü içe aktarın, böylece diğer sorunların yanı sıra döngüsel bir bağımlılık sorunu yaratacak olan SharedModule'u yeniden içe aktarmak zorunda kalmadan PipeModule'a erişim elde edin.

Yukarıdaki "çapraz modül" cevabına başka bir dipnot: PipeModule'u oluşturduğumda forRoot statik yöntemini kaldırdım ve paylaşılan modülümde bu olmadan PipeModule'u içe aktardım. Temel anlayışım, forRoot'un filtreler için zorunlu olarak geçerli olmayan tekil senaryolar için yararlı olduğudur.


1
Bunu eklediğiniz için teşekkürler. Yalnızca Sub-SharedModule
jmcgrath207

Evet, burada da aynı, eksik olan kısım PipesModule'u Sub-SharedModule'a aktarıyordu.
bonfile

1

Bir öne süren alternatif buraya cevabı:

Boru için ayrı bir modül yapmak gerekli değildir , ancak kesinlikle bir alternatiftir. Resmi dokümanlar dipnotunu kontrol edin: https://angular.io/guide/pipes#custom-pipes

Özel borunuzu yerleşik borularla aynı şekilde kullanırsınız.
Borunuzu AppModule'un declarations dizisine dahil etmelisiniz. Borunuzu bir sınıfa enjekte etmeyi seçerseniz, bunu NgModule'unuzun sağlayıcılar dizisinde sağlamalısınız.

Yapmanız gereken tek şey, borunuzu bildirim dizisine ve sağlayıcılar dizisini module, Boruyu kullanmak istediğiniz yere eklemektir .

declarations: [
...
CustomPipe,
...
],
providers: [
...
CustomPipe,
...
]

Ancak tek bir boru 2 modülün parçası olamaz .... Yukarıdaki yaklaşım, farklı modüllerde onu daha ulaşılabilir kılmaktadır.
Himanshu Bansal

0

Not: Yalnızca açısal modüller kullanmıyorsanız

Bazı nedenlerden dolayı bu belgelerde yok, ancak özel boruyu bileşene aktarmak zorunda kaldım

import {UsersPipe} from './users-filter.pipe'

@Component({
    ...
    pipes:      [UsersPipe]
})

1
Yukarıda gönderdiğiniz Plunker'da, borular uygulama modülüne aktarılır (tıpkı bileşenlerde yaptığınız gibi), bu da boruyu o modüldeki tüm bileşenler için kullanılabilir hale getirir.
ABabin

Tamam, aslında özel boruyu kullanan bileşene bakıyordum. Uygulama modülünde küresel olarak içe aktarılabileceğini bilmiyordum. Teşekkürler
Sumama Waheed

users-filter.pipe? neden .pipe?
Nather Webber

1
Bu sadece bir adlandırma kuralı, dosyanın adı users-filter.pipe.ts
Sumama Waheed

2
@SachinThampan olabilir çünkü bu açısal rc5'te iken bence ... o zamandan beri özel olarak NgModule ile bir şeyler değişti. Lütfen NgModule
Sumama Waheed

-1
import { Component, Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'timePipe'
})
export class TimeValuePipe implements PipeTransform {

  transform(value: any, args?: any): any {
   var hoursMinutes = value.split(/[.:]/);
  var hours = parseInt(hoursMinutes[0], 10);
  var minutes = hoursMinutes[1] ? parseInt(hoursMinutes[1], 10) : 0;
  console.log('hours ', hours);
  console.log('minutes ', minutes/60);
  return (hours + minutes / 60).toFixed(2);
  }
}
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Angular';
  order = [
    {
      "order_status": "Still at Shop",
      "order_id": "0:02"
    },
    {
      "order_status": "On the way",
      "order_id": "02:29"
    },
    {
      "order_status": "Delivered",
      "order_id": "16:14"
    },
     {
      "order_status": "Delivered",
      "order_id": "07:30"
    }
  ]
}

Invoke this module in App.Module.ts file.

-2

Kanallarımın bulunduğu dizinde borular için bir modül oluşturdum

import { NgModule } from '@angular/core';
///import pipe...
import { Base64ToImage, TruncateString} from './'  

   @NgModule({
        imports: [],
        declarations: [Base64ToImage, TruncateString],
        exports: [Base64ToImage, TruncateString]
    })

    export class SharedPipeModule { }   

Şimdi bu modülü app.module'a içe aktarın:

import {SharedPipeModule} from './pipe/shared.pipe.module'
 @NgModule({
     imports: [
    ...
    , PipeModule.forRoot()
    ....
  ],

Şimdi iç içe modüle içe aktararak kullanılabilir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.