Ionic Framework — Parte 2

NetCoders
netcoders
Published in
7 min readSep 9, 2015

No artigo anterior ensinamos a configurar o ambiente mínimo necessário para criarmos um aplicativo híbrido com o Ionic Framework e também criamos uma aplicação básica usando o template sidemenu que o Ionic provê para facilitar nosso trabalho. Agora vamos analisar a estrutura do código gerado. Essa análise será o alicerce para entendermos o funcionamento de um aplicativo híbrido.

O arquivo index.html

Dentro da pasta www existe um arquivo chamado index.html. É nesse arquivo que são configuradas todas as bibliotecas que usaremos dentro de nossa aplicação. Nas linhas 7 e 8, podemos ver que existem duas referências a arquivos de estilo (css). A primeira linha é uma referência para os estilos do próprio Ionic e a segunda (style.css) é um arquivo vazio para que você inclua seu layout:

[code language=”css”]
<link href=”lib/ionic/css/ionic.css” rel=”stylesheet”>
<link href=”css/style.css” rel=”stylesheet”>
[/code]

Um pouco mais para baixo temos algumas referências para códigos javascript:

[code language=”js”]
<script src=”lib/ionic/js/ionic.bundle.js”></script>
<script src=”cordova.js”></script>
<script src=”js/app.js”></script>
<script src=”js/controllers.js”></script>
[/code]

O arquivo ionic.bundle.js injeta um framework chamado AngularJS, que foi criado pelo Google e é a base do desenvolvimento em Ionic. Logo abaixo temos o arquivo cordova.js, esse arquivo é responsável por fazer a ponte entre nossa webview e o dispositivo. Depois temos o arquivo app.js e controllers.js. Este é o local onde ficarão todas os controllers de nossa aplicação e aquele é onde ficará a configuração básica de nosso app como as rotas para as views.

Dissecando o arquivo app.js

Como dissemos anteriormente, esse arquivo é onde ficarão as configurações básicas de nosso aplicativo. Vocês podem ver que existem dois blocos de código nesse arquivo, o primeiro é o run e o segundo, o config. Dentro do run devemos destacar o evento ready, e no config as rotas.

O evento ready é chamado sempre que sua aplicação está pronta para ser executada, portanto, deve-se utilizar essa função para executar funções vitais para a aplicação.

[code language=”js”]
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// aqui ficará todo o código que deve ser executado no início de seu app
});
})
[/code]

Já no config temos as declarações das rotas, que são declaradas explicitamente através do $stateProvider.state. É possível notar que o state recebe uma string e um json (o que está dentro de { }). A string é o nome da rota e o json é composto pela url, abstract, templateUrl, controller e views.

O abstract diz ao $stateProvider, que essa rota não é acessível diretamente através da url ‘/app’, pois existem rotas filhas. A url é a rota propriamente dita, que carregará a view (página html) através do templateUrl. Quando uma rota é acionada, o ionic (na verdade é o AngularJs) verifica se existe algum controller para ser executado antes de carregar a view. Caso haja, ele será executado e em seguida a view (html) também será carregada, pois assim a view poderá carregar os dados do escopo do controller. Esse conceito pode parecer estranho a princípio, mas é bem simples. O AngularJs é um framework que pode se comportar como um MVC (Model-View-Controller), dessa maneira, cada view terá um controller e um model. O model armazena as informações e o controller se encarrega de transformar os dados do model em algum formato que será reconhecido pela view.

[code language=”js”]
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state(‘app’, {
url: ‘/app’,
abstract: true,
templateUrl: ‘templates/menu.html’,
controller: ‘AppCtrl’
})
.state(‘app.search’, {
url: ‘/search’,
views: {
‘menuContent’: {
templateUrl: ‘templates/search.html’
}
}
})

$urlRouterProvider.otherwise(‘/app/playlists’);
});
[/code]

Controllers

O arquivo controllers.js é o arquivo que contém todos os controllers de uma aplicação Ionic. Claro que é possível criar outros arquivos onde cada um contém a sua própria controller, o que é, inclusive, uma boa prática. Vale ressaltarmos que essa é uma boa prática para o desenvolvimento, já que os arquivos ficarão organizados, mas para produção é importante executar uma task do Gulp para que os arquivos sejam todos minificados e transformados em um só, por questões de performance.

No exemplo abaixo temos o controller chamado PlaylistsCtrl, que é executado quando a rota app.playlists for chamada. Ele contém um array de objetos JSON chamado playlists. Podemos observar que ele não é um array comum, mas um array que está atrelado a um tal de $scope, que ainda não foi explicado. O AngularJs trabalha com um design pattern chamado Injeção de Dependências, e é justamente esse padrão que está sendo usado nesse contexto, pois se observarmos a assinatura do controller, podemos notar que ele recebe uma string contendo o nome do controller (PlaylistCtrl) e uma função. Na assinatura dessa função temos o tal de $scope, que está sendo injetado para ser usado dentro desse controller. A view (templates/playlists.html) vai receber esse escopo e poderá usar qualquer objeto que estiver acoplado nele. Podemos imaginar o $scope como um guarda-chuva de objetos para determinada view. Mencionamos anteriormente que o AngularJs pode trabalhar como um framework MVC, mas nesse exemplo abaixo, não temos o model separado, pois este está acoplado no próprio $scope do controller.

[code language=”js”]
.controller(‘PlaylistsCtrl’, function($scope) {
$scope.playlists = [
{ title: ‘Reggae’, id: 1 },
{ title: ‘Chill’, id: 2 },
{ title: ‘Dubstep’, id: 3 },
{ title: ‘Cowbell’, id: 6 }
];
})
[/code]

Entendendo as views

No ionic, as views ficam dentro da pasta templates e é possível termos sub-pastas também. Na view abaixo (templates/Playlists.html) temos um código html composto por algumas tags não usuais. Essas tags, na verdade, são diretivas do AngularJs, que é um conceito implementado nesse framework para facilitar a criação e extensão de tags e atributos do html.

Podemos notar o uso da diretiva ion-view, que diz que essa página html é uma view do Ionic. As views possuem conteúdos, que são encapsulados pela diretiva ion-content. No exemplo abaixo, temos também uma lista, representada pela diretiva ion-list e por elementos de lista, representados por ion-item. É possível notar também, que o ion-item possui uma diretiva ng-repeat, que recebe o array que está no $scope (playlists) do controller pertencente à view. E por último, dentro do ion-item, temos o comando {{playlist.title}}. Mas afinal, o que é essa sintaxe estranha {{ }}? O AngularJS utiliza uma sintaxe chamada de Mustache, devido à um interpolador de templates de mesmo nome. Sempre que quisermos mostrar alguma informação que vem de um controller/model devemos usar essa sintaxe. Isso também é utilizado para fazer o que é chamado de two-way data bind, que quer dizer que se houver alterações na variável, playlist, por exemplo, o que estiver entre {{ }} será atualizado para refletir esses novos valores. Com o tempo esse conceito ficará mais claro, mas é importante tentar entendê-lo desde já para que não reste dúvidas.

[code language=”js”]
<ion-view view-title=”Playlists”>
<ion-content>
<ion-list>
<ion-item ng-repeat=”playlist in playlists” href=”#/app/playlists/{{playlist.id}}”>
{{playlist.title}}
</ion-item>
</ion-list>
</ion-content>
</ion-view>
[/code]

Alguns conceitos de AngularJS

O AngularJS, como já mencionamos, é um framework criado pelo Google para facilitar o desenvolvimento de aplicações Web modernas que usam o conceito de SPA (Single Page Applications). Ele provê suporte para two-way data bind, injeção de dependências, comunicação assíncrona, promisses, etc. Vamos discorrer um pouco sobre dois desses conceitos, a injeção de dependências e o two-way data bind.

Mais sobre Injeção de Dependências

Se observarmos os códigos gerados pelo Ionic Framework em nossa aplicação básica, podemos notar que existem parâmetros sendo inseridos nas funções, como por exemplo no código abaixo:

[code language=”js”]
.config(function($stateProvider, $urlRouterProvider) { });
[/code]

No código acima é possível notar dois parâmetros, $stateProvider e $urlRouterProvider. Esses parâmetros não foram declarados em lugar algum, pois pertencem ao AngularJS e foram inseridos diretamente na assinatura da função config, ou seja, eles foram injetados na assinatura da função para serem utilizados dentro do config. De uma forma simplificada, esse é o conceito de injeção de dependências.

O $scope é um exemplo de injeção de dependências no AngularJS e é muito utilizado no Ionic, pois as variáveis acopladas ao $scope estarão disponíveis na views. O exemplo abaixo, que foi extraído da aplicação exemplo, mostra isso com clareza:

[code language=”js”]
.controller(‘PlaylistsCtrl’, function($scope) {
$scope.playlists = [
{ title: ‘Reggae’, id: 1 },

];
})

<ion-list>
<ion-item ng-repeat=”playlist in playlists” href=”#/app/playlists/{{playlist.id}}”>
{{playlist.title}}
</ion-item>
</ion-list>
[/code]

Primeiramente foi adicionado ao $scope do controller PlaylistsCtrl um array chamado playlists. Esse array estará disponível na view relacionada à esse controller, como podemos notar no exemplo.

Two-way Data Bind

O conceito de two-way data bind é, na verdade, bem simples. Imaginemos que temos um textbox na página e gostaríamos que o texto digitado dentro dele fosse exibido em outro lugar, como uma mensagem de boas vindas. O exemplo abaixo mostra justamente isso.

[code language=”js”]
<html ng-app>
<head>
<script src=”//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.min.js”></script>
</head>
<body>
Nome:<input ng-model=”name” type=”text”/>Olá {{name}}
</body>
</html>
[/code]

Nota-se no exemplo acima, que quando digitamos algo dentro do textbox, esse texto aparecerá logo após a palavra “Olá”, pois existe uma “variável” expressa dentro de duplas chaves (Mustache Sintax): {{name}}. Devemos observar que para que isso ocorresse foi necessário definir no textbox uma diretiva do AngularJS chamada ng-model e atribuir a variável name à ela.

Conclusão

Nesse post fizemos uma breve análise do código do app que foi criado no primeiro post sobre Ionic Framework. Podemos constatar que existem diversos conceitos que devem ser estudados para que possamos desenvolver um aplicativo híbrido com o Ionic. O fato de o Ionic utilizar o AngularJS nos trás um grande avanço, pois esse framework é muito bem estruturado e implementa algumas boas práticas de desenvolvimento, como citamos quando falamos sobre injeção de dependências, two-way data bind, etc. Nos próximos posts vamos começar a entender um pouco mais sobre os plugins e sobre alguns comandos do Ionic CLI.

[embed]https://youtu.be/zfMMdmYO-8M[/embed]

--

--