I would like to keep the state of the Md Dialog alive even I close the dialog.So that I can keep the upload status active all over the application. My plan is to store the u
Use the flux architectural pattern for building UI interfaces:
https://facebook.github.io/flux/ (just read about it, don't actually use the facebook API).
It turns out that the pattern is very useful for maintaining application state across multiple components - especially for large scale applications.
The idea is simple - in a flux architecture, data always flows in one direction:
This is true, even when there is an action triggered from the UI:
In your Angular2 application, the dispatcher are your Observables implemented on your service (any component that injects the service can subscribe to it) and the store is a cached copy of the data to aid in emitting events.
Here is an example of a ToDoService that implements the Flux architecture:
import { Injectable } from '@angular/core';
import {Http } from '@angular/http';
import { BehaviorSubject, Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/toPromise';
export interface ToDo {
id: number;
name:string;
isComplete: boolean;
date: Date;
}
@Injectable()
export class ToDoService {
public todoList$:Observable<ToDo[]>;
private subject: BehaviorSubject<ToDo[]>;
private store: {
todos: ToDo[];
}
public constructor(private http:Http) {
this.subject = new BehaviorSubject<ToDo[]>([]);
this.todoList$ = this.subject.asObservable();
this.store = {
todos: []
};
}
public remove(todo:ToDo) {
this.http.delete(`http://localhost/todoservice/api/todo/${todo.id}`)
.subscribe(t=> {
this.store.todos.forEach((t, i) => {
if (t.id === todo.id) { this.store.todos.splice(i, 1); }
});
let copy = this.copy(this.store).todos;
this.subject.next(copy);
});
}
public update(todo:ToDo): Promise<ToDo> {
let q = this.http.put(`http://localhost/todoservice/api/todo/${todo.id}`, todo)
.map(t=>t.json()).toPromise();
q.then(x=> {
this.store.todos.forEach((t,i) => {
if (t.id == x.id) { Object.assign(t, x); }
let copy = this.copy(this.store).todos;
this.subject.next(copy);
});
});
return q;
}
public getAll() {
this.http.get('http://localhost/todoservice/api/todo/all')
.map(t=>t.json())
.subscribe(t=> {
this.store.todos = t;
let copy = Object.assign({}, this.store).todos;
this.subject.next(copy);
});
}
private copy<T>(t:T):T {
return Object.assign({}, t);
}
}
There are several things to notice about this service:
{ todos: ToDo[] }
ToDo[]
list to all of its subscribersAny component that DI injects the Service has an opportunity to subscribe to the todoList$
observable.
In the following component, we take advantage of the async pipe instead of subscribing to the todoList$
observable directly:
Component.ts
ngOnInit() {
this.todoList$ = this.todoService.todoList$;
}
Component.html
<li class="list-group-item" *ngFor="let item of todoList$ | async">
{{ item.name }}
</li>
Whenever a method is called on the service that modifies its internal store, the service updates all of its component subscribers, regardless of which component initiated the change.
The Flux pattern is an excellent pattern for managing complex UIs and reducing the coupling between components. Instead, the coupling is between the Service and the Component, and the interaction is mainly for the component to subscribe to the service.