Escolar Documentos
Profissional Documentos
Cultura Documentos
Indice
1. Código Bonito
2. Página com Subscrições
3. Componentes Dinâmicos, Componentes Específicos e Interfaces
4. Funções de TS
Código Bonito
Antes de se dar uma issue como terminada e enquanto se vai desenvolvendo, deve-se ter em atenção o seguinte:
ng build
npm test (e testes humanos)
*Podem não ser seguidos totalmente à risca, por vezes tem de existir código duplicado ou tem de se usar código deprecated, mas deve ser
analisado.
Usando o SonarLint/ESLint, são mencionados os problemas existentes no código, pelo que esses devem sempre ser analisados e
tentar ao máximo ter o menor número de problemas possível.
Além disso ao correr npm test também são mostrados alguns warnings e erros que também são relacionados pelo ESLint, pelo
que quando possível tentar também corrigir os warnings que vão surgindo ao correr o npm test.
Estrutura Projetos
Os nossos projetos de Angular devem estar organizados por módulos consoante as secções do projeto.
O shared também deve estar organizado.
Nem todos os projetos têm esta estrutura mas tentar fazer algo assim:
app
├── core
│ ├── constants
│ ├── auth
│ ├── interceptor
│ └── ...
├── development
│ ├── ...
│ ├── module1
│ │ ├── pages
| | │ ├── page1 // coisas específicas desta page?
| | │ │ ├── services
| | | │ ├── components
| | | │ └── common
| │ | └── ...
│ │ ├── services // coisas partilhados entre várias pages deste module
│ │ ├── interfaces
│ │ ├── common
│ │ ├── module1.module.ts
│ │ └── module1-routing.module.ts
│ ├── module2
│ ├── ...
│ └── development.route.ts
├── shared
│ ├── components
│ ├── services
│ ├── interfaces
│ ├── common
│ └── ...
└── ...
Página com Subscrições
Na maior parte dos nossos projetos temos páginas de TS que o que fazem é conectarem-se com serviços de FE que fazem
chamadas a serviços de Swagger para fazer pedidos e receber respostas do BE.
Pelo que para isso temos uma estrutura também estabelecida.
Componente TS
Variáveis
isLoading = true -> Será a variável que controla a renderização do conteúdo da página de HTML, pelo que só deve
passar a false, quando já se têm todos os dados e já se fizeram todos os métodos necessários
Para cada set de dados necessários existem váriáveis tipificadas onde esses dados serão guardados.
Para controlar se esses dados já chegaram, isto deve ser feito ou através de um boleano especifico para esses dados ou
se a variável for iniciada a undefined, verfica-se a sua existência. exemplo:
Métodos
ngOnInit() -> Este é o primeiro método que é feito quando se entra na página, pelo que deve chamar qualquer tipo de
métodos que devam logo ser feitos:
initRequests() -> Deve chamar o Init Requests para que as subscrições aos dados sejam iniciadas e ficar à
escuta;
getData() -> Para que sejam chamados os dados necessários
funções que não dependam dos dados -> isto é, podem ser chamadas funções que o que fazem é apenas
inicializar algo, funções que devam ser feitas uma vez e que não dependam de nenhuns dados, exemplo:
initTable, esta função por norma serve para definir uma tabela, ou seja, define as suas colunas e botões
que terá, não precisa de já ter dados para isso.
initRequests() -> Este método contém as várias subscrições aos Subjects de um serviço. As subscrições são inicializadas
e ficam apenas à escuta, o código dentro de cada subscrição não é logo corrido. Só entram lá quando o serviço emite
valor. Ou seja, quando os dados chegam, as suas variáveis especificas são populadas por esses dados e se tiverem
associadas a algum booleano esse passa a false.
Aqui devem estar as subscrições de gets, creates, updates, deletes.
getData() -> Este método deve chamar os pedidos de get do Serviço, para buscar todos os dados necessários.
dataArrived() -> Este método deve ser chamado em todas as subscrições que fizer sentido e vai alterar o isLoading da
página para false, mas deve estar preso e validar a existência de todos os dados de que depende.
Se passar nas condições devem ser feitas todas as funções que dependam dos dados, como transformas dados de uma
tabela, iniciar um formulário de um detalhe de algum objeto e só no fim é que se trocao o isLoading = false.
SubscriptionGetDataComponent
SubscriptionComponent
Exemplo Componente:
export class NewComponent implements OnInit, OnDestroy, SubscriptionGetDataComponent {
readonly subs: Subscription[] = [];
public isLoading = true;
this.subs.push(this.dataServiceFE.otherDataToShow$.subscribe(data => {
this.otherDataToShow = data;
this.isLoadingOtherDataToShow = false;
this.dataArrived();
}),
);
}
getData(): void {
this.databasesService.getDataToShow();
this.databasesService.getOtherDataToShow();
}
// Verifica se os dados já chegaram, ou por boleano ou por variável deixar de ser undefined
dataArrived(): void {
if(this.dataToShow && !this.isLoadingOtherDataToShow){
... funções que dependem destes dados e etc.
this.isLoading = false;
}
}
...
ngOnDestroy(): void {
this.subs.forEach(subscription => {subscription.unsubscribe();
});
}
}
HTML:
<ng-container *ngIf="!isLoading">
...
</ng-container>
Serviço FE
Um serviço de FE para estas páginas, por norma o que faz é a ligação aos pedidos de Swagger para o BE. Pelo que o que vai ter
vão ser os vários métodos que têm de ser feitos, create, updates, gets, deletes e etc. E vai ter os várias váriáveis do tipo subjects,
são estas as subscrições que os componentes estarão à escuta.
Exemplo Serviço:
getDataToShow(): void {
this.dataServiceBE.getDataToShow().subscribe({
next: (result: DataToShow) => {
this.dataToShow$.next(result);
},
error: (result: any) => {
console.error(result);
this.dataToShow$.next([]);
},
});
}
...
Por isso, para cada método do BE, deve existir um método num serviço de FE e deve estar associado a um Subject. Que deverá
ter uma subscrição no componente devido com o código que deve fazer assim que é recebida uma resposta do BE.
Quando possível devem ser usados os componentes dinâmicos já existentes, sendo que estes podem sempre ser
adaptados caso haja a necessidade.
Mesmo sem serem criados componentes dinâmicos, podem ser criados componentes especificos para aquela página,
consoante a sua separação em secções.
A organização dos componentes também deve estar bem estruturada, pelo que componentes dinâmicos devem estar nas
pastas shared, enquanto que componentes mais específicos de certas páginas devem estar junto dessas pastas.
Interfaces
Código deve sempre tentar estar tipificado pois facilita também a deteção e validação de erros.
Interfaces podem extender outras e podem também ser usadas para ter a certeza que um certo componente está a ser
criado da maneira correta, como são aquele caso das interfaces SubscriptionComponent.
Interfaces também devem estar bem organizadas. Interfaces específicas de um só componente seja este dinâmico ou
específico devem estar junto desse componente.
Caso faça sentido no shared também podem interfaces dos componentes do shared numa pasta partilhada.
Funções de TS
Se existirem funções de TS que sejam mais gerais ou que faça sentido estas serem partilhadas, estas devem ir para um
local shared, por exemplo em shared -> common.
Deve-se verificar antes de criar uma nova função se já existe alguma partilhada que faça o pretendido, para evitar a
duplicação de código.
Sempre que possível, separar este tipo de funções mais extensas dos ficheiros de ts dos componentes, para simplificar o
código.