Persist View State
O presente artigo destina-se a explicar o funcionamento da preservação do estado da view, isto é, preservar o conjunto de interações realizadas pelo utilizador sobre uma view.
Overview
Para melhorar a experiência de utilização da aplicação, foi criado um mecanismo que permite guardar qual é o campo da view em que o utilizador está a trabalhar e, sempre que exista um acesso posterior a essa view, a aplicação irá redirecionar para esse campo no seu carregamento. Este redireccionamento tem em conta qual os expanders abertos, extender escolhida e linha da grelha selecionada.
Cada view state é associado a um determinado draft de uma determinada subscrição. Uma subscrição pode ter um conjunto infinito de estados desde que exista o mesmo número de drafts criados.
O view state é preservado utilizando o tipo de cache sessionCache, o que significa que apenas é mantida enquanto a sessão do browser existir
tenha sido feito um refresh à página, fecho da tab, janela ou fecho do browser.
Arquitetura
Os principais componentes existentes são:
ViewState: Estrutura que permite definir o estado de uma view.ViewStateStack: Estrutura que oferece uma API que permite a manipulação de um conjunto de ViewState. Implementa a interfaceICacheblefazendo um contrato com os serviços de cache para assim, poder ser armazenada.ViewStatePersistService: Serviço responsável por preservar o estado de uma view. É utilizada por todos os componentes que queiram notificar e armazenar alterações ao estado da view.
Diagrama de classes
Segue-se o diagrama de class simplificado, onde mostra as relações entre os vários componentes pertencentes à preservação do estado da view, bem como todos aqueles que interagem com estes componentes. Os componentes cujo a sua cor de fundo está a cinzenta, são os componentes principais à preservação do estado da view e os restantes são aqueles que utilizam estes para dizerem que ações foram feitas ao estado da view:

ViewState class
A class ViewState disponibiliza os seguintes atributos:
/*
* Class that represents a state of the view
*/
export class ViewState {
/** Id of the draft that the view state is associated with */
draftId: string;
/** DOM Id element which the view is focus */
domElementId: string;
/** Index line in case of the dom element is inside of a grid */
gridLineIndex: number;
/** List of expanders that are open */
openedExpanders: Array<string>;
/** Extension Id that is visible */
extensionId: string;
/** Grid Id in case of the dom element is inside of a grid */
gridId: string;
}
Serviço ViewStatePercisteService
O serviço ViewStatePercisteService oferece a seguinte API:
/**
* Service responsible to persiste a view state
*/
@Injectable()
export class ViewStatePersisteService {
/**
* Adds a new view state
* @param viewState Object that represents the view state
*/
add(viewState: ViewState) : void;
/**
* Adds or sets (if exists) a new focus dom element id
* @param viewState Object that represents the view state
* @param domElementId DOM Id element which the view is focus
*/
addOrSetDomElement(draftId: string, domElementId: string): void;
/**
* Adds or sets (if exists) a new focus grid line index
* @param draftId Id of the draft that the view state is associated with
* @param gridLineIndex Index line in case of the dom element is inside of a grid
*/
addOrSetGridLineIndex(draftId: string, gridLineIndex: number): void;
/**
* Adds or sets (if exists) a new focus grid id
* @param draftId Id of the draft that the view state is associated with
* @param gridId Grid Id in case of the dom element is inside of a grid
*/
addOrSetGridId(draftId: string, gridId: string): void;
/**
* Adds or sets (if exists) a new focus grid id
* @param draftId Id of the draft that the view state is associated with
* @param extensionId Extension Id that is visible
*/
addOrSetExtensionSelected(draftId: string, extensionId:string): void;
/**
* Adds or sets (if exists) a new view state
* @param viewState Object that represents the view state
*/
addOrSet(viewState: ViewState): void;
/**
* Gets a viewstate from the view state stack
* @param draftId Id of the draft that the view state is associated with
* @param removeNode flag that allows to remove the node if exists
*/
get(draftId: string, removeNode: boolean = false): ViewState;
/**
* Removes a viewstate from the view state stack
* @param draftId Id of the draft that the view state is associated with
*/
remove(drafID: string): void;
/**
* Sets a viewstate from the view state stack
* @param viewState Object that represents the view state
*/
set(viewState: ViewState): void;
/**
* Adds a new open expander to a view state
* @param draftId Id of the draft that the view state is associated with
* @param expanderId Id of the expander that is opened
*/
addOpenedExpander(draftId: string, expanderId: string): void;
/**
* Removes a new open expander to a view state
* @param draftId Id of the draft that the view state is associated with
* @param expanderId Id of the expander that is opened
*/
removeOpenedExpander(draftId: string, expanderId: string): Boolean;
/**
* Verifies if the view state exists
* @param draftId Id of the draft that the view state is associated with
*/
exists(draftId: string): boolean;
}
Pedido de um estado de view preservado
Segue-se o diagrama de sequências de um pedido de estado de view:

Nota: Para mais informações à cerca de como funciona os serviços de cache, bem como a forma correta de os implementar, aceda aqui.
@Author: Ricardo Rocha (ricardo.rocha@primaverabss.com)`