Ich habe eine App, die sich mit einem einzigen Objekttyp befasst. Ich verwalte den Zustand des Objekts mit einem Service. In einer Komponente zeige ich das Objekt an. Von hier aus können Sie auf Felder klicken, um sie in einer anderen Komponente zu bearbeiten. Sie können auch auf Schaltflächen klicken, um einem Feld neue Elemente hinzuzufügen und Elemente zu löschen.Angular 2 Vorlage aktualisiert aber brechen Klickhandler
Die meiste Zeit funktioniert das gut, aber manchmal bricht es ohne irgendwelche Fehlermeldungen. Ich klicke auf die Schaltflächen zum Löschen oder Bearbeiten und es passiert nichts. Die Click-Handler sind defekt (ich habe das in der Konsole überprüft). Dies geschieht normalerweise, nachdem ich ein Array hinzugefügt oder aus einem Array gelöscht habe.
Das ist sehr verwirrend, denn wenn ich ein Element hinzufüge, benutze ich http, um sicherzustellen, dass es in der Datenbank gespeichert wird, und erst nachdem das Observable mit dem neuen Droplet zurückgegeben wurde, lasse ich die Anzeige angular aktualisieren. Und das Display wird immer aktualisiert. Manchmal wird die Anzeige jedoch aktualisiert, aber Augury erkennt nicht, was sehr seltsam ist. Also werde ich einen Hinweis hinzufügen, zum Beispiel wird der Hinweis in der Datenbank sichtbar sein, zurückgegeben werden und die Ansicht wird aktualisiert, aber Augury wird es in der Komponente nicht sehen.
Es ist auch inkonsistent. Manchmal funktioniert es gut.
Hier ist ein Beispielcode aus der Ansicht.
<h4>Hints (optional)</h4>
<button class="btn btn-sm" [routerLink]="['/create/create5']">Add New</button>
<div *ngIf="droplet.hints.length < 1">None</div>
<div class="row" *ngFor="let hint of droplet.hints; let i=index">
<div class="hint col-md-10" (click)="selectHint(i)">
<span [innerHTML]="hint.content || empty"></span>
<span (click)="removeElement(i, 'hint')" class="pull-right glyphicon glyphicon-remove" aria-hidden="true"></span>
</div>
</div>
<h4>Tags
<div class="progress-marker" [class.complete]="droplet.tags.length > 0"></div>
<div class="progress-marker" [class.complete]="droplet.tags.length > 1"></div>
<div class="progress-marker" [class.complete]="droplet.tags.length > 2"></div>
</h4>
<button class="btn btn-sm" [routerLink]="['/create/create6']">Add New</button>
<div *ngIf="droplet.tags.length < 1">None</div>
<br>
<button *ngFor="let tag of droplet.tags; let i=index" type="button" class="btn btn-default btn-sm" (click)="removeElement(i, 'tag')">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span> {{ tag.tag }}
</button>
Es gibt mehrere Felder wie dies aber in der Regel diejenigen, die mit * ngIf sind diejenigen, die Probleme verursachen. Wie ich gesagt habe, wenn ich ein Element in dem Array hinzufüge, entferne oder bearbeite, funktioniert es und die Vorlage wird aktualisiert, aber oft arbeitet danach nichts mehr in den Arrays (obwohl die Nicht-Arrays gut funktionieren).
Die entsprechende Komponente Code sieht wie folgt aus:
import { Component, OnInit } from '@angular/core';
import { Droplet } from '../droplet';
import { DropletService } from '../droplet.service';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs/Rx';
import { HttpService } from '../http.service';
export class ShowDropletComponent implements OnInit {
droplet: Droplet;
constructor(
private dropletService: DropletService,
private router: Router,
private httpService: HttpService
) { }
ngOnInit() {
this.droplet = this.dropletService.getCurrentDroplet();
this.dropletService.pushedDroplet.subscribe(
droplet => this.droplet = droplet
)
}
//using dummy to ensure element not updated unless returned from server
removeElement(index, element) {
console.log("remove clicked");
let dummy = this.droplet;
if (element === "explanation") {
this.router.navigate(['create/create3']);
dummy.explanations.splice(index, 1);
} else if (element === "question") {
this.router.navigate(['create/create4']);
dummy.questions.splice(index, 1);
} else if (element === "hint") {
this.router.navigate(['create/create5']);
dummy.hints.splice(index, 1);
} else if (element === "tag") {
dummy.tags.splice(index, 1);
}
this.httpService.saveDroplet(dummy)
.subscribe(
(droplet: Droplet) => {
this.dropletService.updateCurrentDroplet(droplet);
}
);
}
editThis(field) {
if (field === "description") {
this.router.navigate(['create/create2']);
} else if (field === "name") {
this.router.navigate(['create/create1']);
}
}
selectExplanation(index) {
console.log("select exp clicked");
this.router.navigate(['create/create3', index]);
}
selectQuestion(index) {
console.log("rselect q clicked");
this.router.navigate(['create/create4', index]);
}
selectHint(index) {
console.log("select hint clicked");
this.router.navigate(['create/create5', index]);
}
}
Meine Vermutung ist, dass es etwas ist, mit dem * ngFor Aktualisierung des Array in der Ansicht zu tun, sondern entweder der Index Aktualisierung nicht richtig oder die Klickhandler sind brechen, aber es ist nicht nur mit denen in diesem bestimmten Teil der Vorlage. Ich bin ratlos.
Es scheint, dass Sie jetzt eine Funktion verwenden müssen, wenn Sie trackBy verwenden, was ich getan habe, die ID jedes Artikels zurückgeben. Aber leider hilft es nicht. Ich habe die gleichen Probleme. – Finnjon