View
A view tem como propósito a exibição de dados e comportamentos visuais para o usuário. Em NodeJS, as View Engines são utilizadas para fornecer um mecanismo de renderização de página mais amplo e dinâmico, permitindo assim uma gama maior de possibilidades.
A View Engine utilizada pela JSagon Framework é a Handlebars por padrão. Porém, a mudança para outra Engine é completamente viável utilizando um dos adapters oficiais disponibilizados ou de maneira manual. Além do Handlebars, hoje possuímos compatibilidade oficial com EJS.
Para realizar a alteração da View Engine para o EJS, caso seja de interesse. Faça como a seguir.
Primeiro, será preciso instalar o seguinte módulo.
npm i @jsagon/view-engine-ejs
Agora, precisaremos fazer uma pequena mudança em nosso arquivo dev/src/server.ts passando a factory da View Engine como parâmetro à construção da aplicação, como no exemplo a seguir:
import { JSagon } from '@jsagon/core'
import { ViewEngineFactory } from '@jsagon/view-engine-ejs'
import configApp from './config/app.config'
JSagon.create(configApp, ViewEngineFactory).listen(3000, () => {
console.log('Server online!')
})
Obs.: caso trabalhe com outra View Engine, no final deste artigo será apresentado um meio de configurá-la manualmente.
Entendendo a estrtutura
Todas as views são armazenas em dev/resource/views.
A pasta layouts é onde se encontra o arcabouço das páginas. Nesta pasta se encontram a estrutura base e suas parciais em arquivos separados. Este modelo de estrutura que centraliza o layout evita que em cada página criada seja preciso adicionar sempre a mesma estrutura: cabeçalho, rodapé, menu, etc. Se tornando assim inviável a mudança ao longo do tempo.
Nesse modelo de estrutura em layouts, quando criamos um arquivo de página apenas com o conteúdo principal e ele é requisitado, automaticamente o seu conteúdo será inserido no conteúdo do layout, e será apresentado ao usuário.
Por padrão, o layout é divido nos seguintes arquivos:
main.hbs | arquivo de layout base. Nele são importados os arquivos secundários, e tudo relacionado a css, javascript, entre outros, que será utilizado por toda a aplicação. |
partials/header.hbs | Arquivo que centraliza o cabeçalho da página. |
partials/footer.hbs | Arquivo que centraliza o rodapé da página. |
A pasta dev/resource/views/app é onde serão criadas todas as páginas relacionadas a aplicação seguindo a hierarquia de pastas e convenção de nomes com base na estrutura do back-end.
Exemplo
Digamos que temos o seguinte controlador de nome ProdutoController no caminho a seguir: dev/src/app/FinancasApp/modules/ProdutoFin/Controller/ProdutoController.ts. Com este controlador implementando um método(action) interno de nome "cadastrar" que deverá mostrar uma tela de cadastro.
Caso um caminho não tenha sido explicitamente informado, a aplicação internamente seguindo a convenção de pastas e nomes, irá procurar a view no seguinte caminho: dev/resource/app/financas-app/produto-fin/produto/cadastrar.hbs. E irá renderizá-la de acordo com a explicação do layout.
Cada View Engine possui o seu próprio modelo de tratamento de dados. O que todas têm em comum, é que você pode transitar dados do seu controlador para a sua view.
Exemplo de passagem de dados do controlador para a view:
import { ControllerBase, Request, Response } from '@jsagon/core'
class ProdutoController extends ControllerBase {
public async detalheProduto(req: Request, res: Response) {
return this.render({id:1, nome: 'Empresa ação 1', sobre: 'Ação para compra'})
}
}
export default ProdutoController
O método render da classe ControllerBase define por padrão o caminho da view a ser renderizada.
Exemplo simplificado de utilização dos dados na View, arquivo detalhe-produto.hbs.
<div>
<div>Produto: {{nome}}</div>
<div>Descrição: {{sobre}}</div>
</div>
Para mais informações de como o Handlebars funciona, recomendo um estudo em sua documentação. O mesmo para o EJS.
Se por algum motivo não quiser utilizar layouts, como por exemplo para criação de uma landing page específica. Ou até mesmo se quiser utilizar outro layout ou definir uma outra view a ser utilizada. Faça como algum dos exemplos a seguir:
import { ControllerBase, Request, Response } from '@jsagon/core'
class ProdutoController extends ControllerBase {
public async naoRenderizarLayout(req: Request, res: Response) {
// Não renderiza o layout base definido
return this.render({layout: false})
}
public async alterarLayout(req: Request, res: Response) {
// Altera o layout a ser utilizado.
return this.render({layout: 'caminho/do/layout.hbs'})
}
public async alterarView(req: Request, res: Response) {
// Não renderiza o layout. Caminho a partir de "views"
return this.render({dados: {}}, 'caminho/da/view.hbs')
}
}
export default ProdutoController
Definindo o layout por aplicação
Para definir um layout a ser utilizado por aplicação, é preciso apenas definir na configuração da aplicação o nome do layout em questão. No arquivo dev/src/app/NomeDaAplicacao/app.config.ts tire o comentário da opção "layout" e insira o nome desejado, como a seguir:
module.exports = {
...
// Layout file to be used - Layout a ser usado pelo app
layout: 'nome-novo-layout'
}
View Engine manual
Para as View Engines que a JSagon não possui adapters até o momento, é possível registrá-las da seguinte maneira:
import { JSagon } from '@jsagon/core'
import { ViewEngineFactory } from '@jsagon/view-engine-ejs'
import configApp from './config/app.config'
const bootstrap = JSagon.create(configApp, ViewEngineFactory)
const app = bootstrap.getApplication().getApp()
app.set('view engine', '...')
app.use('...')
bootstrap.listen(3000, () => {
console.log('Server online!')
})
O método getApp executado no exemplo anterior retorna a instancia da plataforma HTTP definida. Neste caso, a instância do Express.
Um passo a mais, aprofundando-se. Ir para Middlewares