Труба '' не найдена angular2 настраиваемая труба
Я не могу исправить эту ошибку. У меня есть панель поиска и ngFor. Я пытаюсь отфильтровать массив с помощью пользовательского канала, как это:
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);
}
}
Использование:
<input [(ngModel)]="searchTerm" type="text" placeholder="Search users">
<div *ngFor="let user of (users | usersPipe:searchTerm)">
...
</div>
Ошибка:
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)">
Угловые версии:
"@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
Убедитесь, что вы не столкнулись с проблемой "кросс-модуля"
Если компонент, который использует канал, не принадлежит модулю, который объявил компонент канала "глобально", то канал не найден, и вы получите это сообщение об ошибке.
В моем случае я объявил трубу в отдельном модуле и импортировал этот модуль трубы в любой другой модуль, имеющий компоненты, использующие трубу.
Я объявил, что компонент, в котором вы используете канал
трубный модуль
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: [],
};
}
}
Использование в другом модуле (например, app.module)
// Import APPLICATION MODULES
...
import { PipeModule } from './tools/PipeModule';
@NgModule({
imports: [
...
, PipeModule.forRoot()
....
],
Ответ 2
Вам нужно включить свой канал в объявление модуля:
declarations: [ UsersPipe ],
providers: [UsersPipe]
Ответ 3
Я нашел ответ "кросс-модуля" выше, очень полезный для моей ситуации, но хотел бы расширить его, поскольку есть еще одна морщина для рассмотрения. Если у вас есть подмодуль, он также не может видеть трубы в родительском модуле в моем тестировании. По этой же причине вам, возможно, придется поместить трубы в отдельный модуль.
Вот краткое описание шагов, которые я предпринял для того, чтобы каналы не были видимыми в подмодуле:
- Возьмите трубы из (родительского) SharedModule и поместите в PipeModule
- В SharedModule импортируйте PipeModule и экспортируйте (для других частей приложения, зависящих от SharedModule, чтобы автоматически получить доступ к PipeModule)
- Для Sub-SharedModule импортируйте PipeModule, чтобы он мог получить доступ к PipeModule без необходимости повторного импорта SharedModule, который мог бы создать проблему с циклической зависимостью, среди других проблем.
Еще одна сноска к вышеперечисленному ответу "кросс-модуль": когда я создал PipeModule, я удалил статический метод forRoot и импортировал PipeModule без этого в моем общем модуле. Мое основное понимание заключается в том, что forRoot полезен для сценариев, таких как одиночные игры, которые не применяются к фильтрам обязательно.
Ответ 4
Для Ionic вы можете столкнуться с несколькими проблемами, как упомянул @Karl. Решение, которое работает безупречно для ионных ленивых загруженных страниц:
- Создайте каталог для каналов со следующими файлами: pipe.ts и pipe.module.ts
//содержимое pipe.ts (внутри может быть несколько каналов, просто не забудьте
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;
}
}
//pipe.module.ts content
import { NgModule } from "@angular/core";
import { IonicModule } from "ionic-angular";
import { toArrayPipe } from "./pipes";
@NgModule({
declarations: [toArrayPipe],
imports: [IonicModule],
exports: [toArrayPipe]
})
export class PipesModule {}
-
Включить PipesModule в раздел импорта app.module и @NgModule
import { PipesModule } from "../pipes/pipes.module"; @NgModule({ imports: [ PipesModule ] });
-
Включите PipesModule в каждый из ваших .module.ts, где вы хотите использовать пользовательские каналы. Не забудьте добавить его в раздел импорта. // Пример. файл: pages/my-custom-page/my-custom-page.module.ts
import { PipesModule } from "../../pipes/pipes.module"; @NgModule({ imports: [ PipesModule ] })
-
Это оно. Теперь вы можете использовать свой собственный канал в своем шаблоне. Ex.
<div *ngFor="let prop of myObject | toArray">{{ prop.key }}</div>
Ответ 5
Примечание: Только если вы не используете angular modules
По какой-то причине это не в документах, но мне пришлось импортировать настраиваемый канал в компонент
import {UsersPipe} from './users-filter.pipe'
@Component({
...
pipes: [UsersPipe]
})
Ответ 6
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.
Ответ 7
Предлагая альтернативный ответ здесь:
Создание отдельного модуля для трубы не требуется, но, безусловно, является альтернативой. Проверьте официальную сноску документации: https://angular.io/guide/pipes#custom-pipes
Вы используете свою собственную трубу так же, как вы используете встроенные трубы.
Вы должны включить свой канал в массив деклараций AppModule. Если вы решите внедрить свой канал в класс, вы должны предоставить его в массиве провайдеров вашего NgModule.
Все, что вам нужно сделать, это добавить свой канал в массив декларации и массив провайдеров в module
где вы хотите использовать канал.
declarations: [
...
CustomPipe,
...
],
providers: [
...
CustomPipe,
...
]
Ответ 8
Я создал модуль для каналов в том же каталоге, где присутствуют мои каналы
import { NgModule } from '@angular/core';
///import pipe...
import { Base64ToImage, TruncateString} from './'
@NgModule({
imports: [],
declarations: [Base64ToImage, TruncateString],
exports: [Base64ToImage, TruncateString]
})
export class SharedPipeModule { }
Теперь импортируйте этот модуль в app.module:
import {SharedPipeModule} from './pipe/shared.pipe.module'
@NgModule({
imports: [
...
, PipeModule.forRoot()
....
],
Теперь его можно использовать, импортировав его во вложенный модуль.