Em resumo, toda aplicação centralizadora deve possuir um arquivo de configuração responsável por gerenciar o mapeamento de rotas do AngularJS para atender as necessidades da aplicação. As rotas estáticas devem ser adicionadas diretamente ao $stateProvider, as demais views da aplicação irão ser carregadas por exceção através do 'otherwise' do $urlRouterProvider.
Utilizando como base a aplicação de referencia, temos esta configuração definida no arquivo config-states.js. Esta configuração tem alta dependência da estrutura de pastas definida para as aplicações.
Por padrão, temos 2 modos de adicionar uma página a aplicação:
As páginas estáticas normalmente estão relacionas a aplicação de centralizadora. Normalmente páginas de configuração, informações e outras. Estas páginas podem ser adicionadas diretamente ao $stateProvider do AngularJS por não possuírem estados.
appStateConfig.$inject = ['$stateProvider', '$urlRouterProvider'];
function appStateConfig($stateProvider, $urlRouterProvider) {
// Views padrões da aplicação que não possuem 'states'.
$stateProvider.state(
'about', {
url: '/html-app/about',
templateUrl: '/html-app/html/about.html'
}
).state(
'blank', {
url: '/',
templateUrl: '/html-app/html/blank.html'
}
);
} // appStateConfig
index.config(appStateConfig); |
Ao contrário das páginas estáticas as views dinâmicas possuem diferentes estados e confiam fortemente na estrutura definida para as aplicações. No caso da aplicação de referencia a chamada das views pode ser realizada a outros contextos, permitindo assim segmentar as aplicações. Entretanto, cada segmento da aplicação deverá seguir a estrura padrão para que seja possível a interação das aplicações convencionais com a centralizadora. Por convenção neste exemplo utilizamos a seguinte especificação:
- <contexto da aplicação>/<contexto da view>/html/<view>/<view>.js
Para possibilitar esta estruturação e carregamento dinâmico, foi utilizado o AngularJS UI Router para permitir sejam feitas views com sub-view.
O arquivo <view>.js deverá ser um descritor de 'estados' para a view. Por padrão o framework procura por um 'state' do tipo '.start' para iniciar a view caso não seja especificado um 'state' na própria chamada.
define(['index', '/html-sample/html/country/country-services.js'], function(index) {
// Inicializa os states da aplicação.
index.stateProvider
// Estado pai, a hierarquia de states é feita através do '.', e todo estado novo
// tem que ter um estado pai, que nesse caso é abstrato. Este status precisa
// apenas de uma template com o elemento <ui-view> para conter os estados filhos.
.state('html-sample/country', {
abstract: true,
template: '<ui-view/>'
})
// Estado inicial da tela deve ser o estado pai com o sufixo '.start' este estado
// será ativado automaticamente quando a tela for carregada.
//
// A URL deve ser compatível com a tela inicial.
//
// No estado também definimos o controller usado na template do estado, e definimos
// o nome do controller em 'controllerAs' para ser utilizado na view.
// também definimos a template ou templateUrl com o HTML da tela da view.
.state('html-sample/country.start', {
url:'/html-sample/country/',
controller:'framework.country-list.Control',
controllerAs: 'controller',
templateUrl:'/html-sample/html/country/country.list.html'
})
// Notar que outros estados também são filhos com sufixos conforme o objetivo da tela,
// assim como o padrão da URL, controller e template.
.state('html-sample/country.detail', {
url:'/html-sample/country/detail/:id',
controller:'framework.country-detail.Control',
controllerAs: 'controller',
templateUrl:'/html-sample/html/country/country.detail.html'
})
.state('html-sample/country.edit', {
url: '/html-sample/country/edit/:id',
controller: 'framework.country-edit.Control',
controllerAs: 'controller',
templateUrl: '/html-sample/html/country/country.edit.html'
})
.state('html-sample/country.new', {
url: '/html-sample/country/new',
controller: 'framework.country-edit.Control',
controllerAs: 'controller',
templateUrl: '/html-sample/html/country/country.edit.html'
});
}); |
Observação: Com a utilização do RequireJS é possível separar o carregamento dos estados para a view dos serviços para a mesma. Portanto, ao definir o descritor de estados podemos solicitar que o mesmo carregue os arquivos de serviços para a view (country-services.js), caso o mesmo já não tenha sido carregado, para isto basta adicionar o caminho completo do arquivo na definição de dependências do RequireJS conforme exemplo acima.