parametros - formularios angular 4
No se pudo encontrar la tubería '''' tubería personalizada angular2 (8)
Parece que no puedo solucionar este error. Tengo una barra de búsqueda y un ngFor. Estoy tratando de filtrar la matriz usando una tubería personalizada como esta:
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);
}
}
Uso:
<input [(ngModel)]="searchTerm" type="text" placeholder="Search users">
<div *ngFor="let user of (users | usersPipe:searchTerm)">
...
</div>
Error:
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)">
Versiones angulares:
"@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"
Asegúrese de no estar enfrentando un problema de "módulo cruzado"
Si el componente que usa la tubería no pertenece al módulo que ha declarado el componente de tubería "globalmente", entonces no se encuentra la tubería y aparece este mensaje de error.
En mi caso, he declarado la tubería en un módulo separado e importé este módulo de tubería en cualquier otro módulo que tenga componentes que utilicen la tubería.
He declarado que el componente en el que está utilizando la tubería es
el módulo de tubería
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: [],
};
}
}
Uso en otro módulo (por ejemplo, app.module)
// Import APPLICATION MODULES
...
import { PipeModule } from ''./tools/PipeModule'';
@NgModule({
imports: [
...
, PipeModule.forRoot()
....
],
Debe incluir su tubería en la declaración del módulo:
declarations: [ UsersPipe ],
providers: [UsersPipe]
Encontré que la respuesta del "módulo cruzado" anterior fue muy útil para mi situación, pero me gustaría ampliarla, ya que hay otra arruga que considerar. Si tiene un submódulo, tampoco puede ver las tuberías en el módulo principal en mis pruebas. Por esa razón también, es posible que deba colocar tuberías en su propio módulo separado.
Aquí hay un resumen de los pasos que tomé para abordar las tuberías que no son visibles en el submódulo:
- Saque las tuberías de SharedModule (padre) y colóquelas en PipeModule
- En SharedModule, importe PipeModule y exporte (para que otras partes de la aplicación que dependen de SharedModule accedan automáticamente a PipeModule)
- Para Sub-SharedModule, importe PipeModule, para que pueda acceder a PipeModule, sin tener que volver a importar SharedModule, lo que crearía un problema de dependencia circular, entre otros problemas.
Otra nota al pie de la respuesta "módulo cruzado" anterior: cuando creé el PipeModule, eliminé el método estático forRoot e importé PipeModule sin eso en mi módulo compartido. Mi comprensión básica es que forRoot es útil para escenarios como singletons, que no se aplican necesariamente a los filtros.
He creado un módulo para tuberías en el mismo directorio donde están presentes mis tuberías.
import { NgModule } from ''@angular/core'';
///import pipe...
import { Base64ToImage, TruncateString} from ''./''
@NgModule({
imports: [],
declarations: [Base64ToImage, TruncateString],
exports: [Base64ToImage, TruncateString]
})
export class SharedPipeModule { }
Ahora importe ese módulo en app.module:
import {SharedPipeModule} from ''./pipe/shared.pipe.module''
@NgModule({
imports: [
...
, PipeModule.forRoot()
....
],
Ahora puede usarse importando lo mismo en el módulo anidado
Para Ionic puedes enfrentar múltiples problemas como mencionó @Karl. La solución que funciona a la perfección para las páginas iónicas con carga lenta es:
- Cree un directorio de tuberías con los siguientes archivos: pipes.ts y pipes.module.ts
// tuberías.ts contenido (puede tener varias tuberías dentro, solo recuerda
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;
}
}
// tuberías.módulo.ts contenido
import { NgModule } from "@angular/core";
import { IonicModule } from "ionic-angular";
import { toArrayPipe } from "./pipes";
@NgModule({
declarations: [toArrayPipe],
imports: [IonicModule],
exports: [toArrayPipe]
})
export class PipesModule {}
-
Incluya PipesModule en la sección de importaciones app.module y @NgModule
import { PipesModule } from "../pipes/pipes.module"; @NgModule({ imports: [ PipesModule ] });
-
Incluya PipesModule en cada uno de sus .module.ts donde desee usar tuberías personalizadas. No olvides agregarlo a la sección de importaciones. // Ejemplo. archivo: páginas / my-custom-page / my-custom-page.module.ts
import { PipesModule } from "../../pipes/pipes.module"; @NgModule({ imports: [ PipesModule ] })
-
Eso es. Ahora puede usar su tubería personalizada en su plantilla. Ex.
<div *ngFor="let prop of myObject | toArray">{{ prop.key }}</div>
Sugiriendo una respuesta alternativa aquí:
No es necesario crear un módulo separado para Pipe, pero definitivamente es una alternativa. Consulte la nota al pie oficial de documentos: https://angular.io/guide/pipes#custom-pipes
Usted usa su tubería personalizada de la misma manera que usa las tuberías integradas.
Debe incluir su canalización en la matriz de declaraciones de AppModule. Si elige inyectar su tubería en una clase, debe proporcionarla en la matriz de proveedores de su NgModule.
Todo lo que tiene que hacer es agregar su canalización a la matriz de
declaraciones
y la matriz de
proveedores
en el
module
donde desea utilizar la canalización.
declarations: [
...
CustomPipe,
...
],
providers: [
...
CustomPipe,
...
]
Nota: solo si no está utilizando módulos angulares
Por alguna razón, esto no está en los documentos, pero tuve que importar la tubería personalizada en el componente
import {UsersPipe} from ''./users-filter.pipe''
@Component({
...
pipes: [UsersPipe]
})
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.