pasar parametros formularios entre directivas diferencia comunicacion componentes componente cli angular typescript

parametros - Angular2 RC5: No se puede vincular a ''Propiedad X'' ya que no es una propiedad conocida de ''Componente secundario''



formularios angular 4 (5)

Hay varias causas posibles para este error:

1) Cuando coloca la propiedad ''x'' entre paréntesis, está intentando vincularla. Por lo tanto, lo primero que debe verificar es si la propiedad ''x'' está definida en su componente con un decorador Input()

Su archivo html:

<body [x]="...">

Tu archivo de clase:

export class YourComponentClass { @Input() x: string; ... }

(asegúrate de que también tienes paréntesis)

2) Asegúrese de haber registrado sus clases de componentes / directivas / tuberías en NgModule:

@NgModule({ ... declarations: [ ..., YourComponentClass ], ... })

Consulte https://angular.io/guide/ngmodule#declare-directives para obtener más detalles sobre las directivas de declaración.

3) También ocurre si tienes un error tipográfico en tu directiva angular. Por ejemplo:

<div *ngif="..."> ^^^^^

En lugar de:

<div *ngIf="...">

Esto sucede porque debajo del capó angular convierte la sintaxis de asterisco a:

<div [ngIf]="...">

Tengo un pequeño proyecto Angular2 basado en el proyecto Angular2 Seed que estoy tratando de actualizar a Angular2 RC5.

Mi proyecto tiene algunas características, una de ellas llamada home . El componente de inicio usa un componente hijo llamado create-report-card-form . He declarado los componentes home y create-report-card-form en el home.module (vea el código a continuación) y obtengo este error :

Rechazo de promesa no controlado: errores de análisis de plantilla: no se puede vincular a ''currentReportCardCount'' ya que no es una propiedad conocida de ''create-report-card-form''.

  1. Si ''create-report-card-form'' es un componente angular y tiene una entrada ''currentReportCardCount'', verifique que sea parte de este módulo.

Estructura del proyecto

-app - app.module.ts - app.component.ts - +home - home.module.ts - home.component.ts - home.component.html - create-report-card-form.component.ts - create-report-card-form.component.html - +<other "features"> - shared - shared.module.ts

home.module

import { NgModule } from ''@angular/core''; import { CommonModule } from ''@angular/common''; import {ReactiveFormsModule} from ''@angular/forms''; import { SharedModule } from ''../shared/shared.module''; import { DataService } from ''../shared/services/index''; import { HomeComponent } from ''./home.component''; import { CreateReportCardFormComponent } from ''./create-report-card-form.component''; @NgModule({ imports: [CommonModule, SharedModule, ReactiveFormsModule], declarations: [HomeComponent, CreateReportCardFormComponent], exports: [HomeComponent, CreateReportCardFormComponent], providers: [DataService] }) export class HomeModule { }

app.module

import { NgModule } from ''@angular/core''; import { BrowserModule } from ''@angular/platform-browser''; import { APP_BASE_HREF } from ''@angular/common''; import { RouterModule } from ''@angular/router''; import { HttpModule } from ''@angular/http''; import { AppComponent } from ''./app.component''; import { routes } from ''./app.routes''; import { AboutModule } from ''./+about/about.module''; import { HomeModule } from ''./+home/home.module''; import {TestModule} from ''./+test/test.module''; import {VoteDataEntryModule} from ''./+vote-data-entry/vote-data-entry.module''; import { SharedModule } from ''./shared/shared.module''; @NgModule({ imports: [BrowserModule, HttpModule, RouterModule.forRoot(routes), AboutModule, HomeModule, TestModule, VoteDataEntryModule, SharedModule.forRoot()], declarations: [AppComponent], providers: [{ provide: APP_BASE_HREF, useValue: ''<%= APP_BASE %>'' }], bootstrap: [AppComponent] }) export class AppModule { }

create-report-card-form.component.ts

import { Component, Input, Output, EventEmitter, OnInit} from ''@angular/core''; import { FormBuilder, FormGroup, FormControl } from ''@angular/forms''; // import { Dialog, Dropdown, SelectItem, Header, Footer, Messages, Message } from ''primeng/primeng''; import { SelectItem, Message } from ''primeng/primeng''; import {ReportCard, ReportCardDataSource} from ''../shared/index''; import {CREATE_REPORT_CARD_FORM_HEADING, EDIT_REPORT_CARD_FORM_HEADING} from ''./constants''; @Component({ moduleId: module.id, selector: ''create-report-card-form'', templateUrl: ''create-report-card-form.component.html'' }) export class CreateReportCardFormComponent implements OnInit { @Input() public reportCardDataSourcesItems: SelectItem[]; @Input() public reportCardYearItems: SelectItem[]; @Input() errorMessages: Message[]; @Output() reportCardCreated = new EventEmitter<ReportCard>(); @Output() editReportCardFormValueChanged = new EventEmitter<ReportCard>(); public editReportCardForm: FormGroup; private selectedReportCardDataSourceIdControl: FormControl; private selectedReportCardYearControl: FormControl; // TODO: remove this hack for resetting the angular 2 form once a real solution is available (supposedly in RC5) private isFormActive: boolean = true; private formHeaderString: string = CREATE_REPORT_CARD_FORM_HEADING; private formDialogVisible: boolean = false; private isCreatingNewReportCard = false; // false implies that we are updating an existing report card constructor(private fb: FormBuilder) { } configureForm(selectedReportCard: ReportCard, createNewReport: boolean) { this.isCreatingNewReportCard = createNewReport; this.resetForm(); this.selectedReportCardDataSourceIdControl.updateValue(selectedReportCard.reportCardDataSource.reportCardSourceId); this.selectedReportCardYearControl.updateValue(selectedReportCard.reportCardYear); if (createNewReport) { this.formHeaderString = CREATE_REPORT_CARD_FORM_HEADING; } else { // updating an existing report card this.formHeaderString = EDIT_REPORT_CARD_FORM_HEADING + selectedReportCard.reportCardYear + '' '' + selectedReportCard.reportCardDataSource.reportCardSourceName; } this.editReportCardForm.valueChanges.subscribe(data => this.onFormValueChanged(data)); } customGroupValidator(reportCardDataSourceIdControl: FormControl, reportCardYearControl: FormControl, isCreatingNewReportCard: boolean) { return (group: FormGroup): { [key: string]: any } => { // missing data error ... if (!reportCardDataSourceIdControl.value || !reportCardYearControl.value) { return { ''requiredDataError'': ''Report card year AND provider must be selected.'' }; } // invalid data error ... if (isCreatingNewReportCard) { if (!reportCardDataSourceIdControl.touched || !reportCardYearControl.touched) { return { ''requiredDataError'': ''Report card year AND provider must be selected.'' }; } } else { if (!reportCardDataSourceIdControl.touched && !reportCardYearControl.touched) { return { ''requiredDataError'': ''Report card year OR provider must be selected.'' }; } } // return null to indicate the form is valid return null; }; } hideFormDialog() { this.formDialogVisible = false; } showFormDialog() { // hide any previous errors this.errorMessages = []; this.formDialogVisible = true; } createForm() { // by default, configure the form for new report card creation by setting // the initial values of both dropdowns to empty string this.selectedReportCardDataSourceIdControl = new FormControl(''''); this.selectedReportCardYearControl = new FormControl(''''); this.editReportCardForm = this.fb.group({ selectedReportCardDataSourceIdControl: this.selectedReportCardDataSourceIdControl, selectedReportCardYearControl: this.selectedReportCardYearControl }, { validator: this.customGroupValidator(this.selectedReportCardDataSourceIdControl, this.selectedReportCardYearControl, this.isCreatingNewReportCard), asyncValidator: this.duplicateReportCardValidator.bind(this) }); } duplicateReportCardValidator() { return new Promise(resolve => { if ((this.errorMessages) && this.errorMessages.length === 0) { resolve({ uniqueReportCard: true }); } else { resolve(null); } }); } showError(errorMessages: Message[]) { this.errorMessages = errorMessages; } ngOnInit() { this.createForm(); } onEditReportCardFormSubmitted() { let newReportCard = this.getReportCard( this.selectedReportCardDataSourceIdControl.value, this.selectedReportCardYearControl.value, this.reportCardDataSourcesItems ); this.reportCardCreated.emit(newReportCard); } resetForm() { this.createForm(); this.isFormActive = false; setTimeout(() => this.isFormActive = true, 0); } onFormValueChanged(data: any) { let newReportCard = this.getReportCard( this.selectedReportCardDataSourceIdControl.value, this.selectedReportCardYearControl.value, this.reportCardDataSourcesItems ); this.editReportCardFormValueChanged.emit(newReportCard); } private getReportCard(reportCardDataSourceIdString: string, reportCardYearString: string, reportCardDataSourceItems: SelectItem[]): ReportCard { let selectedReportCardYear: number = Number(reportCardYearString); let selectedProviderReportCardId: number = Number(reportCardDataSourceIdString); let selectedProviderReportCardName: string = ''Unknown Report Card''; for (var i = 0; i < this.reportCardDataSourcesItems.length; i++) { var element = this.reportCardDataSourcesItems[i]; if (Number(element.value) === selectedProviderReportCardId) { selectedProviderReportCardName = element.label; break; } } let reportCard: ReportCard = new ReportCard(); reportCard.reportCardYear = selectedReportCardYear; reportCard.reportCardDataSource = new ReportCardDataSource( selectedProviderReportCardId, selectedProviderReportCardName ); return reportCard; } }

create-report-card-form.component.html

<p-dialog header={{formHeaderString}} [(visible)]="formDialogVisible" [responsive]="true" showEffect="fade " [modal]="true" width="400"> <form *ngIf="isFormActive" [formGroup]="editReportCardForm" (ngSubmit)="onEditReportCardFormSubmitted()"> <div class="ui-grid ui-grid-responsive ui-fluid " *ngIf="reportCardDataSourcesItems "> <div class="ui-grid-row "> <p-dropdown [options]="reportCardDataSourcesItems" formControlName="selectedReportCardDataSourceIdControl" [autoWidth]="true"></p-dropdown> </div> <div class="ui-grid-row "> <p-dropdown [options]="reportCardYearItems" formControlName="selectedReportCardYearControl" [autoWidth]="true"></p-dropdown> </div> <div class="ui-grid-row "> <p-messages [value]="errorMessages"></p-messages> </div> <footer> <div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix "> <button type="submit" pButton icon="fa-check " [disabled]="!editReportCardForm?.valid" label="Save "></button> </div> </footer> </div> </form> </p-dialog>

home.component.ts

import { Component, OnInit, ViewChild } from ''@angular/core''; // // import { REACTIVE_FORM_DIRECTIVES } from ''@angular/forms''; // import {ROUTER_DIRECTIVES} from ''@angular/router''; // import { InputText, Panel, SelectItem, Message, Growl, Dialog, DataTable, Column, Header, Footer, Tooltip } from ''primeng/primeng''; import { Message, SelectItem } from ''primeng/primeng''; import {CreateReportCardFormComponent} from ''./create-report-card-form.component''; import { ReportCardDataSource, ReportCard, ProviderData, DataService, DUPLICATE_REPORT_CARD_MESSAGE } from ''../shared/index''; import {ReportCardCommands} from ''./enums''; /** * This class represents the lazy loaded HomeComponent. */ @Component({ moduleId: module.id, selector: ''sd-home'', templateUrl: ''home.component.html'', styleUrls: [''home.component.css''] //,directives: [CreateReportCardFormComponent] }) export class HomeComponent implements OnInit { public growlMessages: Message[] = []; public createReportCardError: Message[] = []; public reportCardDataSourcesItems: SelectItem[] = [{ label: ''Select Provider'', value: '''' }]; public reportCardYearItems: SelectItem[] = [{ label: ''Select Year'', value: '''' }]; public providerData: ProviderData = new ProviderData(); public displayReportCardDeleteConfirmation: boolean = false; private isCreatingNewReportCard: boolean = true; private selectedReportCard: ReportCard; @ViewChild(CreateReportCardFormComponent) private createReportCardFormComponent: CreateReportCardFormComponent; constructor(private dataService: DataService) { } ngOnInit() { let reportCardDataSources: ReportCardDataSource[] = this.dataService.getReportCardDataSources(); for (var i = 0; i < reportCardDataSources.length; i++) { var element = reportCardDataSources[i]; this.reportCardDataSourcesItems.push({ label: element.reportCardSourceName, value: element.reportCardSourceId }); // retrieve data from localStorage if available this.providerData = this.dataService.getProviderData(); } // initialize report card years const minYear: number = 2000; // TODO: maxYear should be sourced from the server by a service let maxYear: number = (new Date()).getFullYear(); for (var i = maxYear; i >= minYear; i--) { this.reportCardYearItems.push({ value: i.toString(), label: i.toString() }); } } // Returns the index of the report card in providerData.reportCards that has the same reporCardSourceId // and reportCardYear as selectedReportCard, or -1 if there is no match. indexOf(selectedReportCard: ReportCard): number { return this.providerData.reportCards.findIndex(x => x.reportCardDataSource.reportCardSourceId === selectedReportCard.reportCardDataSource.reportCardSourceId && x.reportCardYear === selectedReportCard.reportCardYear); } onReportCardCreated(newReportCard: ReportCard) { if (newReportCard) { if ((this.indexOf(newReportCard) > -1)) { // attemp to create a duplicate report card; show error this.setCreateReportCardFromErrorMessage(DUPLICATE_REPORT_CARD_MESSAGE); } else { if (this.isCreatingNewReportCard) { // save new report card this.createReportCardError = []; this.createReportCardFormComponent.hideFormDialog(); this.providerData.reportCards.splice(0, 0, newReportCard); this.createReportCardFormComponent.hideFormDialog(); } else { // update existing report card let reportCardToUpdateIndex: number = this.indexOf(this.selectedReportCard); if (reportCardToUpdateIndex > -1) { this.providerData.reportCards[reportCardToUpdateIndex].reportCardDataSource.reportCardSourceId = newReportCard.reportCardDataSource.reportCardSourceId; this.providerData.reportCards[reportCardToUpdateIndex].reportCardDataSource.reportCardSourceName = newReportCard.reportCardDataSource.reportCardSourceName; this.providerData.reportCards[reportCardToUpdateIndex].reportCardYear = newReportCard.reportCardYear; } } this.dataService.storeProviderData(this.providerData); this.isCreatingNewReportCard = true; this.clearCreateReportCardFormErrorMessage(); this.createReportCardFormComponent.hideFormDialog(); } } } editReportCardFormValueChanged(newReportCard: ReportCard) { if (this.indexOf(newReportCard) === -1) { // clear duplicate report card error message in ''create report card'' dialog this.clearCreateReportCardFormErrorMessage(); } else { // set duplicate report card error message this.setCreateReportCardFromErrorMessage(DUPLICATE_REPORT_CARD_MESSAGE); } } onAddReportCardButtonClicked() { this.isCreatingNewReportCard = true; this.createReportCardFormComponent.configureForm(new ReportCard(), this.isCreatingNewReportCard); this.createReportCardFormComponent.showFormDialog(); } onReportCardDeleteButtonClicked(reportCard: ReportCard) { this.reportCardCommandExecute(reportCard, ReportCardCommands.Delete); } onReportCardEditButtonClicked(reportCard: ReportCard) { this.reportCardCommandExecute(reportCard, ReportCardCommands.EditReportCard); } onAddVotesRouterLinkClicked(reportCard: ReportCard) { this.reportCardCommandExecute(reportCard, ReportCardCommands.EditVotes); } onReportCardDeleteConfirmButtonClick(isDeleteOk: boolean) { if (isDeleteOk) { this.providerData.reportCards.splice(this.providerData.selectedReportCardIndex, 1); // store updated reportCards in local storage this.dataService.storeProviderData(this.providerData); } this.displayReportCardDeleteConfirmation = false; } reportCardCommandExecute(reportCard: ReportCard, command: ReportCardCommands) { this.providerData.selectedReportCardIndex = this.indexOf(reportCard); this.selectedReportCard = reportCard; switch (command) { case ReportCardCommands.EditVotes: this.dataService.storeProviderData(this.providerData); break; case ReportCardCommands.Delete: this.displayReportCardDeleteConfirmation = true; break; case ReportCardCommands.EditReportCard: this.isCreatingNewReportCard = false; this.createReportCardFormComponent.configureForm(reportCard, this.isCreatingNewReportCard); this.createReportCardFormComponent.showFormDialog(); break; default: break; } } private setCreateReportCardFromErrorMessage(message: Message) { this.createReportCardError = []; this.createReportCardError.push(message); this.createReportCardFormComponent.showError(this.createReportCardError); } private clearCreateReportCardFormErrorMessage() { this.createReportCardError = []; this.createReportCardFormComponent.showError(this.createReportCardError); } }

home.component.html

<p-growl [value]="growlMessages" sticky="sticky"></p-growl> <p-dataTable [value]="providerData.reportCards" [paginator]="true" rows="15" [responsive]="true"> <header> <div> <h1>Report Cards ({{providerData.reportCards.length}})</h1> </div> <button type="button" pButton icon="fa-plus" (click)="onAddReportCardButtonClicked()" label="Add" title="Add new report card"></button> </header> <p-column styleClass="col-button"> <template let-reportCard="rowData"> <button type="button" pButton (click)="onReportCardEditButtonClicked(reportCard)" icon="fa-pencil" title="Edit report card"></button> </template> </p-column> <p-column field="reportCardDataSource.reportCardSourceName" header="Report Card" [sortable]="true"></p-column> <p-column field="reportCardYear" header="Year" [sortable]="true"></p-column> <p-column header="Votes" [sortable]="false"> <template let-reportCard="rowData"> {{reportCard.votes.length}} <!--<button type="button" pButton icon="fa-pencil-square" (click)="editVotes(reportCard)" title="Edit votes"></button>--> <a [routerLink]="[''/votes'']" (click)="onAddVotesRouterLinkClicked(reportCard)">Edit</a> </template> </p-column> <p-column styleClass="col-button"> <template let-reportCard="rowData"> <button type="button" pButton (click)="onReportCardDeleteButtonClicked(reportCard)" icon="fa-trash" title="Delete report card"></button> </template> </p-column> </p-dataTable> <create-report-card-form [currentReportCardCount]="providerData.reportCards.length" [reportCardDataSourcesItems]="reportCardDataSourcesItems" [reportCardYearItems]="reportCardYearItems" (reportCardCreated)=onReportCardCreated($event) (editReportCardFormValueChanged)=editReportCardFormValueChanged($event)> </create-report-card-form> <p-dialog header="Confirm Deletion" [(visible)]="displayReportCardDeleteConfirmation" modal="modal" showEffect="fade"> <p> Delete the following report card and all related data (<strong>NO undo</strong>)? </p> <p> <strong>{{providerData?.reportCards[providerData.selectedReportCardIndex]?.reportCardDataSource?.reportCardSourceName}}</strong><br/> <strong>{{providerData?.reportCards[providerData.selectedReportCardIndex]?.reportCardYear}}</strong> </p> <footer> <div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"> <button type="button" pButton icon="fa-close" (click)="onReportCardDeleteConfirmButtonClick(false)" label="No"></button> <button type="button" pButton icon="fa-check" (click)="onReportCardDeleteConfirmButtonClick(true)" label="Yes"></button> </div> </footer> </p-dialog>


Lo arreglé agregando el prefijo (attr.):

<create-report-card-form [attr.currentReportCardCount]="expression" ...

Lamentablemente, esto no se ha documentado correctamente todavía.

más detalles here


Me encontré con el mismo error, cuando olvidé declarar mi componente personalizado en mi NgModule : verifique allí, si las otras soluciones no funcionarán para usted.


Si usa la CLI angular para crear sus componentes, digamos CarComponent , adjunta la app al nombre del selector (es decir, app-car ) y esto arroja el error anterior cuando hace referencia al componente en la vista principal. Por lo tanto, debe cambiar el nombre del selector en la vista principal para decir <app-car></app-car> o cambiar el selector en CarComponent a selector: ''car''


<create-report-card-form [currentReportCardCount]="providerData.reportCards.length" ... ^^^^^^^^^^^^^^^^^^^^^^^^

En su plantilla HomeComponent, está intentando vincular a una entrada en el componente CreateReportCardForm que no existe.

En CreateReportCardForm, estas son sus únicas tres entradas:

@Input() public reportCardDataSourcesItems: SelectItem[]; @Input() public reportCardYearItems: SelectItem[]; @Input() errorMessages: Message[];

Agregue uno para currentReportCardCount y debería estar listo para comenzar.