2

Je mehr ich mit meiner Website in Angular 2 voranschreite, desto mehr scheint die Elvis Operator die magische Kraft zu sein, die alles möglich macht. Jeder Schritt, den ich unternommen habe, bestand darin, herauszufinden, wie man es auf alle Fälle, in denen alles mit den Daten gemacht wird, richtig anwendet. Ich denke, wenn es "normal" wäre, ein ? auf praktisch alles, was Sie im wirklichen Leben mit tatsächlichen Daten tun, die Angular Docs würde es erwähnen.Wie kann ich vermeiden, den Elvis Operator zu benutzen?

Um ein Beispiel zu geben, habe ich gerade erst gelernt, wie FormGroups für reaktive Formen einrichten. Im Anschluss an die Schritte auf Angular.io sah meine Formulargruppe so aus.

createForm() { 
    this.quesForm = this.fbuild.group({ 
     question: this.featureQuestion.question, 
     id  : this.featureQuestion.id, 
     name : this.featureQuestion.name, 
     answers : this.fbuild.array([]) 
    }); 
    this.setAnswers(this.featureQuestion.answers); 
} 

get answers(): FormArray { 
    return this.quesForm.get('answers') as FormArray; 
}; 

mit dem mock-data arbeitete ich in einem const geschaffen funktionierte es völlig in Ordnung. Wenn ich es jedoch mit "echten Daten" "real-world" machen wollte, musste ich noch 3 oder 4 Tage damit verbringen, zu entdecken, dass ich das tun musste.

createForm() { 
    this.quesForm = this.fbuild.group({ 
     question: this.featureQuestion ? this.featureQuestion.question: '', 
     id  : this.featureQuestion ? this.featureQuestion.id: '', 
     name : this.featureQuestion ? this.featureQuestion.name: '', 
     answers : this.fbuild.array([]) 
    }); 
    this.setAnswers(this.featureQuestion ? this.featureQuestion.answers: []); 
} 

Es spielt keine Rolle, ob ich in die html bin Bindung an ein Attribut zu binden, die durch @Input und @Output oder in einer Funktion, etwas zu tun; Die Elvis Operator ist der Troll an der Brücke mit einem verrückten Rätsel, das eine Woche dauert, um herauszufinden, was ich dachte, ich lernte. Zuerst dachte ich, es wäre nur eine kleine Eigenart, die sie sich erarbeiten mussten, aber jetzt ist es für mich persönlich zu groß, als dass es ein bloßer Bug an ihrem Ende wäre, sonst würde ich wohl mehr Informationen darüber finden, weil das würde bedeuten, dass niemand in der Lage wäre, Angular im wirklichen Leben zu benutzen, ohne es bei jedem Schritt anzuwenden. Was bedeutet, dass es etwas ist, was ich mache.

Hier ist ein Beispiel, wie ich derzeit meine Daten von Firebase aufrufen.

Dienst

export class HomeService { 
    BusImage : FirebaseObjectObservable<any>; 

    constructor(private af: AngularFire) {} 

    getBusImage() { 
     this.BusImage = this.af.database.object('/page_area_business_image') 
     as FirebaseObjectObservable<any> 

     return this.BusImage; 
    } 
} 

geordnete Komponente

export class ExpBusinessComponent implements OnInit { 

    private busImageO  : FirebaseObjectObservable<any>; 
    private busImageQues01O : FirebaseObjectObservable<any>; 
    private busImageQues02O : FirebaseObjectObservable<any>; 

    constructor(private _homeService: HomeService) {} 

    ngOnInit() { 
     this._homeService.getBusImage().subscribe(BusImage => { 
      this.busImageO  = BusImage.expand; 
      this.busImageQues01O = BusImage.questions.question01; 
      this.busImageQues02O = BusImage.questions.question02; 
     }); 
    } 
} 

Eltern Vorlage

<h1>{{busExpInformation?.title}}</h1> 
<p>{{busExpInformation?.intro}}</p> 

<business-image 
    [busImageI]  = "busImageO" 
    [busImageQues01I] = "busImageQues01O" 
    [busImageQues02I] = "busImageQues02O"> 
</business-image> 

Kinder Komponente

export class BusinessImageComponent implements OnChanges, OnInit { 
    @Input('busImageI')   busImage : FirebaseObjectObservable<any>; 
    @Input('busImageQues01I') question01 : FirebaseObjectObservable<any>; 
    @Input('busImageQues02I') question02 : FirebaseObjectObservable<any>; 

    public selectedI(selected){ this.selectedAnswer = selected }; 

    selectedAnswer: any; 

    expbTrigger   : boolean = false; 
    expb2Trigger  : boolean = false; 
} 

Kinder Vorlage

<multiple-choice-radio *ngIf="expbTrigger" 
    [question] = "question01" 
    (selectedO) = "selectedI($event)" 
></multiple-choice-radio> 

Grandchild Komponente

export class MultipleChoiceRadioComponent implements OnInit, OnChanges { 
    @Input('question') featureQuestion: QuestionModel; 
    @Output() selectedO: EventEmitter<any> = new EventEmitter(); 

    selected = {value1: '', value2: ''}; 

    quesForm: FormGroup; 

    public sendAnswer =(): void => { 
     this.selectedO.emit(this.selected); 
    } 

    constructor(private fbuild : FormBuilder) {} 

    ngOnChanges() { 
     this.createForm(); 
    } 

    createForm() { 
     this.quesForm = this.fbuild.group({ 
      question: this.featureQuestion ? this.featureQuestion.question: '', 
      id  : this.featureQuestion ? this.featureQuestion.id: '', 
      name : this.featureQuestion ? this.featureQuestion.name: '', 
      answers : this.fbuild.array([]) 
     }); 
     this.setAnswers(this.featureQuestion ? this.featureQuestion.answers: []); 
    } 

    get answers(): FormArray { 
     return this.quesForm.get('answers') as FormArray; 
    }; 

    setAnswers(answers : Answers[]){ 
     const answersFGs  = answers.map(answers => this.fbuild.group(answers)); 
     const answersFormArray = this.fbuild.array(answersFGs); 

     this.quesForm.setControl('answers', answersFormArray); 
    } 

    getSelected(ans) { 
     this.selected = { value1: ans.id, value2: ans.answer }; 

    } 
} 

Grandchild Vorlage

<form [formGroup]="quesForm" novalidate> 
    <fieldset [attr.id]="quesForm.value.id"> 

     <label> 
      {{quesForm.value.question}} 
     </label> 

     <div> 

      <div *ngFor="let ans of quesForm.value.answers"> 
       <div> 

        <input type="radio" 
         [attr.name] = "quesForm.value.name" 
         [attr.id] = "ans.id" 
         [attr.value] = "ans.answer" 
         (click)  = "getSelected(ans)" 
         (click)  = "sendAnswer()" 
         hidden 
        /> 

        <label [attr.for]="ans.id"> 
         {{ans.answer}} 
        </label> 
       </div> 
      </div> 

     </div> 

    </fieldset> 
</form> 

Die meisten der Code, den ich nur weggelassen vorgesehen Prozesse zu eliminieren, die im Grunde genau die gleiche Sache sind nur mit verschiedene Daten gehen an verschiedene Orte, ich habe auch Klassen aus dem HTML eliminiert, weil ich Bootstrap benutze, der den Kabeljau auffüllt Ing.

Von jetzt an die @Output Senden der ausgewählten Wert bis zum Elternteil gibt nur Ergebnisse in einigen Testbindung Ich habe mit einem | json Rohr auf das gesamte Objekt, aber Protokolle als undefiniert, also wenn Sie das Gefühl, dass etwas mit mir falsch ist mache ich das, ich bin mir schon bewusst, dass es nicht richtig funktioniert.

Der Grund, warum ich Dinge auf diese Weise mache abgesehen davon, dass es die einzige Möglichkeit ist, Dinge zu bekommen defined ist, weil die GrandChild Component wird an anderer Stelle in der Website für andere Fragen verwendet werden. Manchmal verwende ich nur die id, um Logik auszulösen, manchmal ziehe ich die Antwort in eine Instanz von Benutzerdaten, die in der Datenbank gespeichert werden. Es ergab also keinen Sinn, einfach das gesamte Modell in die Kette zu schicken, nur um ein paar Werte zu extrahieren, und wenn der Wert selbst die Daten sein könnte, die die Verschachtelung von verschachtelten Werten verhindern, wenn man bedenkt, wie ich nicht kann ziehe meine Daten ohne die Elvis Operator irgendwo richtig angewendet.

Ich bin auf Tonnen von Winkeltricks gestoßen, die ich versucht habe, nur für sie zu verwenden, weil es immer undefined kam, als ich versuchte, zu lernen, wie es funktioniert, was extra schwer war, weil ich es nicht wusste wenn ich etwas falsch gemacht habe, wenn es darum ging, es zum Laufen zu bringen, oder wenn ich etwas falsch gemacht habe, was die Anwendung des Elvis Operator betrifft. Ich habe hier aufgrund von Downvotes und Anfragen, sie zu schließen, einige Fragen gelöscht, weil aus der Perspektive derjenigen von euch, die mit Angular Meister sind, es eine schreckliche Frage war oder eine schreckliche Art, sie zu stellen. Hoffentlich kann jemand helfen, herauszufinden, was ich mit meinen Daten machen muss, um Dinge einfach so zu machen, wie es Angular.io ohne all die zusätzlichen unerwarteten Fehlerbehebungen und Workarounds vorschlägt, einfach weil ich eine tatsächliche Datenbank anrufe und nicht spotte -Daten lokal definiert

Antwort

1

Sie verwenden reaktive Formulare, was bedeutet, dass Sie am Ende trotzdem eine Menge Code haben.

Verwenden Sie einfach Vorlagenvorlagen, es sei denn, Sie haben spezielle Anforderungen für reaktive Formulare.

0

Sie können größere Bereiche mit *ngIf einwickeln, um nicht einmal zu dem Punkt zu kommen, an dem ?. erforderlich ist.

<h1>{{busExpInformation?.title}}</h1> 
<p>{{busExpInformation?.intro}}</p> 

könnte

<ng-container *ngIf="busExpInformation"> 
    <h1>{{busExpInformation.title}}</h1> 
    <p>{{busExpInformation.intro}}</p> 
</ng-container> 

Wenn Sie Ihre ganze Komponenten Vorlage wickeln mit einer solchen ng-container und listet alle Asynchron geladen Felder mit busExpInformation && a && b && c, dann könnte es nie eine Notwendigkeit für ?.

Sie sein kann auch einen Resolver verwenden, um zu verhindern, dass die Komponente sogar hinzugefügt wird, bevor Daten verfügbar sind (https://angular.io/docs/ts/latest/guide/router.html#!#resolve-guard)

Verwandte Themen