7

Ich versuche zu verwenden Formbuilder in einer Seite, die ich in Ionic haben zu verwenden 2.Wie Angular 2 der Formbuilder zwischen mehreren Komponenten

Als erstes ist hier meine Umgebung Details ist: Laufen auf 10 Windows und ionische läuft - -Ausführung gibt mir 2.0.0-beta.35

Hier ist ein Teil meiner package.json Datei:

... 
"@angular/common": "2.0.0-rc.3", 
"@angular/compiler": "2.0.0-rc.3", 
"@angular/core": "2.0.0-rc.3", 
"@angular/forms": "^0.3.0", 
"@angular/http": "2.0.0-rc.3", 
"@angular/platform-browser": "2.0.0-rc.3", 
"@angular/platform-browser-dynamic": "2.0.0-rc.3", 
"ionic-angular": "2.0.0-beta.10", 
"ionic-native": "1.3.2", 
"ionicons": "3.0.0" 
... 

Zweitens hier sind die beiden wichtigsten Dateien beteiligt: ​​

insight.ts

import { Component } from '@angular/core'; 
import {NavController, NavParams} from 'ionic-angular'; 
import { 
    REACTIVE_FORM_DIRECTIVES, 
    FormBuilder, 
    FormControl, 
    FormGroup 
} from '@angular/forms'; 
import { App, Insight } from '../../models'; 
import { InsightProvider } from '../../providers/insight/insight.service'; 
import { InsightImage, InsightLabel, InsightLink, InsightQuestion, InsightThought, InsightTodo, InsightVideo } from './shared'; 

@Component({ 
    templateUrl: 'build/pages/insight/insight.html', 
    directives: [REACTIVE_FORM_DIRECTIVES, InsightImage, InsightLabel, InsightLink, InsightQuestion, InsightThought, InsightTodo, InsightVideo], 
    providers: [App, InsightProvider, FormBuilder] 
}) 
export class InsightPage { 

    canAdd: boolean; 
    showDetails: boolean; 
    newInsight: Insight; 
    insightForm: FormGroup; 

    constructor(private insightProvider: InsightProvider, 
       private params: NavParams) { 
    this.insightForm = new FormGroup({ 
     type: new FormControl('', []), 
     todo: new FormControl('', []), 
     checked: new FormControl(false, []), 
     imageUrl: new FormControl('', []), 
     link: new FormControl('', []), 
     url: new FormControl('', []), 
     label: new FormControl('', []), 
     question: new FormControl('', []), 
     answer: new FormControl('', []), 
     title: new FormControl('', []), 
     details: new FormControl('', []), 
    }); 
    } 

    ngOnInit() { 
    this.canAdd = false; 
    this.showDetails = true; 
    } 

    addNewInsight() { 
    if (this.newInsight.type) { 
     this.insightProvider.createInsight(this.newInsight) 
     .subscribe(response => { 
     this.newInsight.setId(response.data.id); 
     this.newInsight.title = ''; 
     console.log(response); 
     }); 
    } 
    } 

    deleteClicked(index: number) { 
    console.log('Clicked on ' + index); 
    this.insightProvider.deleteInsight(this.newInsight) 
    .subscribe(data => { 
     console.log(data); 
    }); 
    } 


} 

insight.html

<form [ngFormModel]="insightForm" (ngSubmit)="createNewInsight()"> 
     <ion-item> 
     <ion-label for="type">Insight Type</ion-label> 
     <ion-select name="type" id="type" [formControl]="type"> 
      <ion-option value="label">Label</ion-option> 
      <ion-option value="thought">Thought</ion-option> 
      <ion-option value="link">Link</ion-option> 
      <ion-option value="question">Question</ion-option> 
      <ion-option value="todo">Todo</ion-option> 
      <ion-option value="image">Image</ion-option> 
      <ion-option value="video">Video</ion-option> 
     </ion-select> 
     </ion-item> 

     <div [ngSwitch]="type"> 
      <insight-image [form]="insightForm" *ngSwitchCase="'image'"></insight-image> 
      <insight-label [form]="insightForm" *ngSwitchCase="'label'"></insight-label> 
      <insight-link [form]="insightForm" *ngSwitchCase="'link'"></insight-link> 
      <insight-question [form]="insightForm" *ngSwitchCase="'question'"></insight-question> 
      <insight-thought [form]="insightForm" *ngSwitchCase="'thought'"></insight-thought> 
      <insight-todo [form]="insightForm" *ngSwitchCase="'todo'"></insight-todo> 
      <insight-video [form]="insightForm" *ngSwitchCase="'video'"></insight-video> 
     </div> 

     <button type="submit" block primary text-center (click)="addNewInsight()" [disabled]="!newInsight.type"> 
     <ion-icon name="add"></ion-icon> Add Insight 
     </button> 
    </form> 

Wie Sie sehen können, ich versuche das passieren FormGroup-Objekt in mehrere Komponenten, so dass ich sie verwenden könnte. Hier

ist ein Beispiel dafür, was eine der Komponenten aussieht (Minimalversion jetzt):

<ion-item> 
    <ion-label floating for="link">Link</ion-label> 
    <ion-input type="text" name="link" id="link" [formControl]="link"></ion-input> 
</ion-item> 

<ion-item> 
    <ion-label floating for="url">URL</ion-label> 
    <ion-input type="text" id="url" name="url" [formControl]="url"></ion-input> 
</ion-item> 

Das Problem, das ich bin vor gerade jetzt dieser Fehler ist:

Error from FormBuilder and Ionic 2

Was ich glaube, ist, dass der FormBuilder nach den angegebenen Namen sucht, die ich in meiner Typoskriptdatei deklariere (wie todo, imageUrl, link, usw.), aber da es in meinen anderen Komponenten ist, ist es fehlerhaft, weil es nicht dort ist .

Was könnte der Grund für diesen Fehler sein? Ich habe online gesucht und konnte keine verwandten Probleme finden.

FYI, der Grund, warum ich sie in Komponenten und nicht auf der gleichen Seite brauche, ist, weil in Zukunft die Funktionalität für jede Eingabe anders sein wird, also benötigt jeder Komponente eine "Single Responsibility".

Vielen Dank im Voraus

+0

Sie nicht Version von Ionic2 erwähnt haben Sie verwenden, kann es wichtig sein. Ich bin mir nicht sicher, aber der Fehler sagt "unspezifizierter Name", also versuchen Sie 'ngControl =" url "' anstelle von '[formControl] =" url "' – dafyk

+0

Ich habe gerade meine Frage aktualisiert, um meine Umgebungsdetails an der Spitze zu enthalten. Danke, dass du mich daran erinnerst, dich über meine Umgebung zu informieren. Ich habe versucht ngControl = "url", aber ich bekomme jetzt "Kein Provider für ControlContainer". Ich habe "ControlContainer" als Provider in meiner Komponente hinzugefügt, erhalte aber denselben Fehler. Nur für den Fall, ich habe versucht, formControl = "url" Ich bekomme den gleichen Fehler –

+1

Nun Ionic2 ist noch Beta, erwarten einige brechen Änderungen gemäß [Formulare bevorstehenden Änderungsvorschlag] (https://docs.google.com/document/u/1/d/1RIezQqE4aEhBRmArIAS1mRIZtWFf6JxN_7B4meyWK0Y/pub). Meine nächste Schätzung ist die Verwendung von 'formControlName =" url "' – dafyk

Antwort

20

Für jeden sonst mit Problem ist

Cannot find control with unspecified name attribute.

Das Problem vergessen hat formControlName auf dem Formular Eingabeelement zu definieren.

formControlName="url"

Wenn Sie No provider for NgControl nach dem Fixieren Eingängen zugewandt sind, haben Sie ein Problem mit Ionic2 Änderungen in Fom Handhabung zu brechen. Es gibt eine Chance, dass Sie Ihren Code durch Importieren einer neuen Formularkomponente beheben:

import { disableDeprecatedForms, provideForms } from '@angular/forms';

Aber Sie werden wahrscheinlich nach wie vor immer mehr Probleme.Um wirklich den Code zu beheben:

  • Update auf die neueste Beta-Version
  • vereinfachen Sie Ihre Form zu 2 einfachen Eingaben
  • Ihre Form umschreiben und es
  • hinzufügen funktioniert Rest Ihrer Elemente

Gutes Tutorial über FormBuilder und Validierung https://blog.khophi.co/ionic-2-forms-formbuilder-and-validation/

+4

Danke! Ich benutze '[formControlName] =" url "' anstelle von 'formControlName =" url "' – Kevin

+0

Wie oben, danke dafür. – Arg0n

+0

Wenn Sie formArrays verwenden, müssen Sie den Namen in 'formArrayName =" name "' in einem div um die * ngFor-Schleife angeben, die die verschiedenen Formulare ausgibt – triadiktyo

3

Als In Angular 2+ habe ich festgestellt, dass die Annahme eines konsistenten Ansatzes für die Angabe von formGroupName, formArrayName und formGroupNames viel Zeit gespart hat und was von meiner Vernunft übrig geblieben ist. Ich habe viel Zeit verloren, bevor ich es tat.

Entweder verwenden

formXXXName="literal value" 

Oder

formXXXName="{{value expression}}" 

Oder

[formXXXName]="'literal value'" (single tick within double tick) 

Oder

[formXXXName]="value expression" 

I wa Ich mische sie ständig zu meinem großen Leid.

Beispiel aus einem aktuellen Projekt:

Fall 1: Korrekte Verwendung von Dirac-Notation.

<label>Notes</label> 
    <div class="panel panel-default"> 
     <div class="panel-body"> 
      <div [formArrayName]="'notes'"> 
       <div *ngFor="let note of outletForm.controls.notes.controls; let i=index"> 
        <input type="text" [formControlName]="i" class="form-control" /> 
       </div> 
      </div> 
     </div> 
    </div> 

Fall 2: Korrekte Verwendung der Nicht-Klammer-Notation.

<label>Notes</label> 
    <div class="panel panel-default"> 
     <div class="panel-body"> 
      <div formArrayName="notes"> 
       <div *ngFor="let note of outletForm.controls.notes.controls; let i=index"> 
        <input type="text" formControlName="{{i}}" class="form-control" /> 
       </div> 
      </div> 
     </div> 
    </div> 

Bitte beachten Sie bei der oben der Verwendung von „{{“ und „}}“ Angular zu zwingen, zu behandeln, was normalerweise einen Zeichenkette Wert sein würde (wegen der Verwendung der nicht-Klammern Syntax) als ein EL-Ausdruck.

Fall 3: Eine falsche Verwendung des Dirac-Notation

<label>Notes</label> 
    <div class="panel panel-default"> 
     <div class="panel-body"> 
      <div [formArrayName]="notes"> 
       <div *ngFor="let note of outletForm.controls.notes.controls; let i=index"> 
        <input type="text" formControlName="{{i}}" class="form-control" /> 
       </div> 
      </div> 
     </div> 
    </div> 

In diesem Fall wird der Wert von formArrayName, "Hinweise", wird als ein EL-Expression behandelt. Da meine Komponente kein solches Mitglied hat, wird nichts ausgewertet. Daher wird der folgende Fehler erlitten:

OutletFormComponent.html:153 ERROR Error: Cannot find control with unspecified name attribute 
    at _throwError (forms.es5.js:1830) 
    at setUpFormContainer (forms.es5.js:1803) 
    at FormGroupDirective.addFormArray (forms.es5.js:4751) 
    at FormArrayName.ngOnInit (forms.es5.js:5036) 
    at checkAndUpdateDirectiveInline (core.es5.js:10793) 
    at checkAndUpdateNodeInline (core.es5.js:12216) 
    at checkAndUpdateNode (core.es5.js:12155) 
    at debugCheckAndUpdateNode (core.es5.js:12858) 
    at debugCheckDirectivesFn (core.es5.js:12799) 
    at Object.eval [as updateDirectives] (OutletFormComponent.html:159) 

Glücklicherweise ist die Zeilennummer ganz am Boden des Stapels Punkte auf der Linie mit dem Problem gegeben.

Fall 4: Eine falsche Verwendung von nicht-Bracketing Notation

<label>Notes</label> 
    <div class="panel panel-default"> 
     <div class="panel-body"> 
      <div [formArrayName]="'notes'"> 
       <div *ngFor="let note of outletForm.controls.notes.controls; let i=index"> 
        <input type="text" formControlName="i" class="form-control" /> 
       </div> 
      </div> 
     </div> 
    </div> 

In diesem Fall wird der Wert von formControlName, „i“, wird als Zeichenkette interpretiert werden, aber wir wirklich auf die Bezug nehmen wollen Indexvariable 'i' in der containing * ngFor-Anweisung.Das Ergebnis dieses Fehlers ist:

OutletFormComponent.html:161 ERROR Error: Cannot find control with path: 'notes -> i' 
    at _throwError (forms.es5.js:1830) 
    at setUpControl (forms.es5.js:1738) 
    at FormGroupDirective.addControl (forms.es5.js:4711) 
    at FormControlName._setUpControl (forms.es5.js:5299) 
    at FormControlName.ngOnChanges (forms.es5.js:5217) 
    at checkAndUpdateDirectiveInline (core.es5.js:10790) 
    at checkAndUpdateNodeInline (core.es5.js:12216) 
    at checkAndUpdateNode (core.es5.js:12155) 
    at debugCheckAndUpdateNode (core.es5.js:12858) 
    at debugCheckDirectivesFn (core.es5.js:12799) 

Vielen Dank und viel Lob an alle Angular2 + Entwickler und Experten.

0

Wenn Sie den FormBuilder verwenden, müssen Sie in Ihrer Vorlage das Steuerelement definieren, damit der FormBuilder das Steuerelement identifizieren kann.

So in der Vorlage, die mit einer Steuer ‚url‘ eine formGroup namens ‚insightForm‘ hat:

<form [formGroup]="insightForm" (ngSubmit)="onSubmit(insightForm.value)"> 
    <ion-input [formControl]="insightForm.controls['url']"></ion-input> 
</form> 
Verwandte Themen