Angular2 so aktualisieren Sie ein Element in eine observable-collection
Update, kurz:
Ich bin auf der Suche nach den Gegenwert von etwas wie das zu tun, aber für eine Beobachtbare eher als ein normales array:
var i = this.customers.findIndex(customer => customer._id === id);
~i && this.customers[i] = newObject.
Habe ich 2 Komponenten auf dem Bildschirm. Eine list-Komponente auf der linken Seite und einer Komponente für die Anzeige auf der rechten Seite (stellen Sie sich vor, dass es eine PDF-Datei, die nur stur die neueste version der Daten)
Wenn Sie auf ein Element in der Liste, zeigt es die Daten für das ausgewählte Element in die Komponente auf der rechten Seite.
Die Liste ist ein observable-array:
items$: Observable<Proposal[]>;
Jedes Element in der Liste hat eine untergeordnete Komponente. Es ist möglich, auf ein Symbol auf einem einzelnen Element, die änderungen der Daten des Kindes. Das Kind hat ein Ereignis emitter zu sagen, die Eltern die Daten geändert hat:
@Output() proposalDataChanged: EventEmitter<string> = new EventEmitter();
Den Eltern bindet es:
<fb-proposal-list-item
[proposal]="proposal" (proposalDataChanged)="handleDataChanged(p)">
</fb-proposal-list-item>
Das problem, das ich habe, ist, dass in der handleDataChanged Methode, die ich suchen will, die Beobachtbaren, für das Element, das geändert wurde, und ersetzen Sie es mit der neuen payload zurückgegeben, die von der emitter. Ich will nicht den server aufrufen, aktualisieren Sie die gesamte Liste.
Muss ich tun, damit die Komponente auf der rechten Seite spiegelt die neuen Daten.
Ich bin in der Lage, das Element zu finden, wie diese:
handleDataChanged(data: Proposal){
this.items$.subscribe((items: Proposal[]) => item = items.find(p => p.id
== data.id));
}
aber kann nicht herausfinden, wie man den Artikel aktualisieren in der öffentlichkeit, eher als die Suche nach der einen, der geändert wurde.
Ich weiß, ich kann 'trick' die Komponente, indem Sie die Navigation woanders und dann wieder zurück zu zwingen, es zu aktualisieren, aber das trifft auch auf die API (und die lädt die Seite auch).
So sieht die url aus:
/pages/proposals/manage/-XHzOJY/document
Dass slug in der url ist die id des aktuell ausgewählten Element (welches ist gerendert in der Komponente auf der rechten Seite).
So kann ich nicht verwenden, params change detection hier, weil es nicht ändern. Der Anwender verursacht eine änderung der bereits ausgewählten Objekt aus, das ist eine von vielen innerhalb der observable-array.
UPDATE
Hier ist der vollständige code für die übergeordnete Komponente:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable, Subject } from 'rxjs/Rx';
import { Proposal } from '../proposal';
import { ProposalService } from '../proposal.service';
import { SearchService } from '../../services/search-service';
@Component({
selector: 'fb-proposal-list',
templateUrl: './proposal-list.component.html',
styleUrls: ['./proposal-list.component.css']
})
export class ProposalListComponent implements OnInit {
total$: Observable<number>;
items$: Observable<Proposal[]>;
term: string = "";
currentPage: number = 1;
private pageStream = new Subject<number>();
constructor(
private _searchService: SearchService,
private _proposalService: ProposalService,
private _router: Router) {
}
ngOnInit() {
this.setupSearching();
//let timer = Observable.timer(0, 60000);
//timer.subscribe(() => this.goToPage(this.currentPage));
}
setupSearching(){
const searchSource = this._searchService.searchTermStream
.map(searchTerm => {
this.term = searchTerm;
return {search: searchTerm, page: 1}
});
const pageSource = this.pageStream.map(pageNumber => {
this.currentPage = pageNumber;
return {search: this.term, page: pageNumber}
});
const source = pageSource
.merge(searchSource)
.startWith({search: this.term, page: this.currentPage})
.switchMap((params: {search: string, page: number}) => {
return this._proposalService.getProposalsPaged(params.search, params.page)
})
.share();
this.total$ = source.pluck('meta').pluck('total_items');
this.items$ = source.pluck('items');
}
goToPage(page: number) {
this.pageStream.next(page)
}
handleDataChanged(id: string){
this.goToPage(this.currentPage);
}
}
InformationsquelleAutor rmcsharry | 2017-03-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich glaube nicht, dass Sie verstehen, wie Observablen Arbeit. Was Sie hier nennen "beobachten Sammlung" ist nicht das, was Sie vielleicht denken, es ist, wie in der "Sammlung der beobachtbaren Elemente".
Was es ist, tatsächlich, ist ein Strom der emittierten Sammlungen. Also, wenn Sie
Observable<Model[]>
, es ist nicht eine Sammlung, die beobachtet, indem einige Beobachter, dass es tatsächlich einen Strom emittiertModel[]
Sammlungen. In diesem Sinne, Sie können nicht aktualisieren Sie die emittierte Wert (offensichtlich, da es bereits ausgestrahlt wurde), aber was Sie wollen, ist es für beobachtbare zu emittieren eine weitere, aktualisierte Sammlung vonModel
.Bevor Sie versuchen, werden Sie haben, um zu wissen, dass man nicht Strahlen etwas aus beobachten, die Sie nicht selbst erstellt haben. Was Sie brauchen, ist ein Subjekt, ein Objekt, das sowohl Observable und Observer (es erbt von beiden Beobachter und Beobachtende interfaces).
Also, lasst uns bauen sowas:
Angenommen, Sie bekommen Ihre Vorschläge aus einigen API-Aufruf:
Und nun möchten Sie Ihre Daten aktualisieren:
Dies mag wie eine Menge und ich würde empfehlen, das Lesen mehr auf, wie die Observablen, die Arbeit für die künftigen Probleme, die Sie haben könnten. Cheers.
Das problem ist, dass ich schon ein Thema, da die Liste ausgelagert wird. Ich werde fügen Sie den vollständigen code für die übergeordnete Komponente.
Gut, Sie können einfach konvertieren Sie die
_items$
zuSubject
fügen Sie eine neuethis._items
Sammlung und fügen Sie eine get -items$
wie in meinem Beispiel. Wenn Sie möchten, aktualisieren Sie die Elemente, sondern nur das tun, was ich Ihnen gezeigt habe in der letzten Methode, die in meiner Antwort.Danke, jetzt verstehe ich. 🙂
InformationsquelleAutor Adnan A.
Du kannst es in folgenden weisen
| async
RohrInformationsquelleAutor Aniruddha Das