Arquivo da tag: single page application

AngularJS – Diretivas

pic_angularOlá pessoal. Dando continuidade ao meu estudo sobre o angular, deixo aqui registrado o que estudei e entendi sobre diretivas.

Diretivas dão poder ao programador para estender/ampliar o comportamento de elementos HTML, e é responsável pela manipulação do DOM. Uma diretiva é capaz de selecionar um elemento HTML por seu atributo (associado ao nome da diretiva), ou nome do elemento, ou por um comentário, ou mesmo pelo valor do atributo class.

Ao selecionar um elemento HTML, a diretiva pode ampliar seu comportamento, adicionando um novo HTML, manipulando o DOM, ou ainda associando eventos à funções Javascript.

São diversas as diretivas nativas do angular: ng-controller, ng-model, ng-repeat, ng-show, ng-hide, ng-click, ng-blur, ng-change, ng-checked, ng-focus, ng-keydown, ng-keypress, ng-keyup, e diversas outras.

Podemos criar nossas próprias diretivas (Custom Directives), para por exemplo:

    • Criar componentes como: abas, janelas de mensagens, janelas pop-up, calendário, etc…;
    • Intercecptar a vinculação de dados e tratá-los se necessário;
    • Criar uma esquema padronizado para validação do model;
    • Tratar eventos dos elementos HTML;
    • Etc…

Uma diretiva customizada deve estar associada a um módulo, podendo ser o próprio módulo da página:

<body ng-app="myApp">
    <div minha-diretiva></div>
</body>
var app = angular.module('myApp', []);

app.directive('minhaDiretiva', function () {
   return {
	restrict: 'A',
	link: function (scope, elem, attrs) {
		elem[0].innerHTML = "minha diretiva....";
	}
   }
});

No exemplo acima, a função directive() do módulo, é usada para criar uma diretiva chamada “minhaDiretiva”, retornando um objeto literal com suas definições. A propriedade restrict é usada para especificar como a diretiva irá selecionar o elemento HTML. Os valores válidos para restrict são:

  • ‘A’ – Atributo:
  • ‘E’ – Elemento:
  • ‘C’ – Class:
  • ‘M’ – Comentário:

A propriedade link deve ser associada a uma função de ligação que faz o trabalho de definição da diretiva. Parâmetros da função: scope, elem e attrs.

  • scope: dá acesso ao escopo da diretiva;
  • elem: é um objeto JQuery Lite contendo o elemento encontrado pela diretiva;
  • attrs: é um objeto que mantém todas as propriedades do objeto encontrado pela diretiva.

O resultado final após a execução da diretiva é:

<div minha-diretiva="">minha diretiva....</div>

Agora vou alterar a diretiva anterior para localizar elementos HTML pelo nome (customizado) da tag do elemento. Com angular, posso criar meus tipos de elemento HTML e definir seu comportamento.

<body ng-app="myApp">
    <minha-diretiva></minha-diretiva>
</body>
var app = angular.module('myApp', []);

app.directive('minhaDiretiva', function () {
   return {
	restrict: 'E',
	link: function (scope, elem, attrs) {
		elem[0].innerHTML = "minha diretiva....";
	}
   }
});

O resultado final é:

<minha-diretiva>minha diretiva....</minha-diretiva>

Observação: é padrão no angular o nome da diretiva seguir a nomenclatura: “primeira palavra iniciando em minusculo e demais com inicial maiúscula”, por exemplo: minhaDiretiva, janelaMensagem, etc. No momento de usar (no HTML) fica assim (dash-delimited): minha-diretiva, janela-mensagem, etc.

Utilizando o conceito de diretivas, também é possível criar templates utilizando as propriedades template ou templateUrl do objeto de retorno de definição da diretiva.

Avançando um pouco mais, mas nem tanto. Uma diretiva também pode ser um template. Observe:

<span meu-template="meu primeio template...">
app.directive('meuTemplate', function () {

    return {

        restrict: 'A',
        scope: {},
        link: function (scope, elem, attrs) {
            scope.msg = attrs.meuTemplate;
        },
        template: '<div><strong>{{msg}}</strong></div>',
        replace: false
    }
});

Ao usar a diretiva acima, obtém-se o seguinte resultado após a renderização:

<span meu-template="meu primeio template...">
    <div>
	 <strong>meu primeio template...</strong>
   </div>
</span>

O conteúdo da propriedade template da diretiva foi incluído dentro do elemento span selecionado pela diretiva. Isso ocorreu devido a propriedade replace estar configurada como false. Se configurado com true, o elemento span é totalmente substituído pelo conteúdo do template, observe o resultado da renderização:

<div meu-template="meu primeio template...">
   <strong>meu primeio template...</strong>
</div>

Há também no objeto de definição da diretiva para elementos (restrict: ‘E’) uma propriedade chamada transclude, que é capaz e anexar/incluir elementos (do contêiner selecionado pela diretiva) dentro do template da diretiva.

E para finalizar, segue um exemplo (simplório) de diretiva para mostrar áreas de mensagens.

app.directive('msgAlert', function () {

    return {
        restrict: 'A',
        scope: { textoMsg: '@'},
               
        template: '<div class="msgAlert">{{textoMsg}} <input type="button" value="(fechar)" ng-click="esconder()" /></div>',
        replace: true,
               
        link: function (scope, elemento, attrs) {
            scope.esconder = function () {
                scope.$parent.mostrarAlert = false;
            }
        }
    };
});

<style>
    .msgAlert {
        background-color:#ffd800;
        border: 1px solid #808080;
        padding: 5px;
        margin: 5px;  
   }
</style>

<div msg-alert texto-msg="{{msg}}" ng-show="mostrarAlert"></div>
<input type="button" value="mostrar alerta" ng-click="abrirAlert()" />

Conclui que usar diretivas não é tão fácil. :-(

AngularJS – Introdução

pic_angularOlá pessoal, inicio aqui meu aprendizado no tão falado framework do Google, o AngularJS. Os textos aqui representam o que tenho estudado e aprendido a respeito deste framework.

AngularJS é um framework Javascript open-source mantido pela Google que dá poder aos desenvolvedores para criar aplicações Web baseadas em navegadores, como as aplicações SPA – Single Page Application.

O site oficial é https://angularjs.org/.

Vamos ao Olá Mundo!!!

<html>
<head>
    <title>Olá Mundo</title>
    <script src="angular.min.js"> </script>
    <script>
        var app = angular.module('minhapagina', []);
    </script>
</head>
<body ng-app="minhapagina">
    <p>Olá mundo: {{ 1 + 2 }}</p>
</body>
</html>

O exemplo acima, consiste em uma simples página HTML, a não ser pelo atributo ng-app. Os “angularianos” chamam ng-app de diretiva, e normalmente é aplicada a tag BODY ou HTML, e indica o elemento inicial da aplicação (ponto a partir do qual o Angular pode ser usado dentro do código HTML).

O código javascript destacado no exemplo, localiza a diretiva ng-app, transformando a página num módulo gerenciável pelo o framework.

 
var app = angular.module('minhapagina', [])

O texto “{{ 1 + 2 }}” é avaliado como uma expressão pelo Angular, que ao ser executada, o resultado é concatenado ao HTML do contexto que está inserida. Uma expressão deve estar entre chaves duplas.

Outras principais diretivas:

ng-controller: define uma função Javascript para controlar determinada parte da página;
ng-model: vincula o elemento a uma propriedade do model do seu contexto;
ng-repeat: realiza a iteração em um array (basicamente um foreach);
ng-show: deixa visível um elemento HTML de acordo com um valor booleano (true/false). Também aceita expressões lógicas;
ng-hide: esconde o elemento de acordo com um valor booleano (true/false). Aceita expressões lógicas;

A referência completa das diretivas é obtida em https://docs.angularjs.org/api/ng/directive/.

Existem diretivas para tratar os diversos eventos disponibilizados nos elementos HTML: ng-click, ng-blur, ng-change, ng-checked, ng-focus, ng-keydown, ng-keypress, ng-keyup, e diversas outras.

O angularJS e o padrão MVC.

Normalmente encontramos a implementação do padrão MVC na programação que ocorre no lado do servidor da aplicação. Com o angular é diferente, a implementação ocorre no lado cliente da aplicação.

O padrão MVC é composto por três componentes principais:

Model – Componente responsável por gerenciar os dados para a aplicação. Não é de responsabilidade do model como o usuário vê os dados e qual lógica será aplicada sobre eles.

View – Componente que representa visualmente o model, um pedaço do HTML da página. Exibe os dados para o usuário devidamente organizados em estruturas HTML e CSS. Não é de sua responsabilidade a lógica contida no controller nem no model.

Controller – Componente responsável por preparar o model para a view, além de tratar regras de negócios, tratar eventos da view e requisições ao servidor.

angular_mvc

Vamos a um segundo exemplo.

<script>
   var app = angular.module('minhapagina', []);
</script>
<body ng-app="minhapagina">
     Seu primeiro nome é: <input type="text" ng-model="primeironome" />
     <p>{{primeironome}}</p>
</body>

Entendendo o exemplo: a diretiva ng-model vincula o valor de elementos input, select e textarea a uma propriedade no model chamada “primeironome”. Neste exemplo, a propriedade “primeironome” do model, mantém o valor informado no input, sendo possível, por exemplo, dentro da view usar expressões para recuperar seu valor.

Efeito igual é conquistado usando a diretiva ng-bind, que auto alimenta a propriedade innerHTML do elemento HTML com o valor de uma propriedade do model.

<p ng-bind="primeironome"></p>

Por questão de padronização do HTML e para deixar válido junto ao W3C, é possível utilizar o prefixo data- (dataset do HTML5) antes das diretivas:

data-ng-app
data-ng-model=”primeironome”
data-ng-bind

Vamos entender melhor a diretiva ng-controller.

Um controller é atribuído a um pedaço da página HTML (view) através da diretiva ng-controller. O controller é uma função Javascript (do tipo construtora) que tem por objetivo cuidar e atualizar de uma determinada área do DOM do página (um pedaço da página, a view).

Como regra geral, um controlador não deve fazer referência ou manipular o Document Object Model (DOM) diretamente.

Controllers são responsáveis pela interação entre models e views. A vinculação de dados entre model e view é realizada pelo angularJS de forma dinâmica, ou seja, qualquer alteração ocorrida em um dos lados (model ou view) atualiza o outro lado, é o chamado Two-Way DataBing [atualização de duas vias] (isso pode ser observado no primeiro exemplo: ao digitar no input, a propriedade “primeironome” é atualizada simultaneamente).

O acesso à view pelo controller é realizado através do objeto $scope. O $scope é um parâmetro do controller que dá acesso ao model vinculado a view.

Vamos a um simples exemplo sobre Controller.

HTML:

    <div ng-controller="MinhaControladora">
        <input type="button" ng-click="perguntar()" value="OK" />
        <p ng-bind="nome"></p>
    </div>

JS:

var app = angular.module('myApp', []);

app.controller('Controladora1', ['$scope', function ($scope) {

	$scope.nome = "...";

	$scope.perguntar = function () {
		$scope.nome = prompt("Qual seu nome?");
	};
}]);

Analisando o bloco da função controladora acima, foi definido a propriedade “nome” e o método “perguntar”. O parâmetro $scope estabelece uma conexão entre a model e view. No bloco HTML representando a view, as propriedades e métodos do models podem ser acessadas e vinculados aos elementos HTML.

Vamos a um exemplo menos simples (mas não avançado) sobre Controller. Destaque para a diretiva ng-repeat para iterar um array.

Javascript:

var app = angular.module('myApp', []);

app.controller('principal', ['$scope', function ($scope) {

	$scope.item = "";
	$scope.msg = "";
	$scope.itens = [];

	$scope.adicionar = function () {


		if ($scope.item == "") {
			alert("Informe o texto");
		}
		else {


			if ($scope.itens.indexOf($scope.item) == -1) {
				$scope.itens.push($scope.item);
				$scope.msg = "";
				$scope.item = "";
			}
			else {
				$scope.msg = "Item existente.";
			}
		}
	};

	$scope.excluir = function (item)
	{
	
		var pos = -1;
		for (var i = 0; i < $scope.itens.length; i++) {

			if ($scope.itens[i] == item)
			{
				pos = i;
				break;
			}
		}

		if (pos > -1)
			$scope.itens.splice(pos, 1);
	}
}]);

HTML:

<body ng-app="myApp" ng-controller="principal">
    <input type="text" ng-model="item" />
    <input type="button" ng-click="adicionar()" value="adicionar" />
    <div mostrar-msg></div>
    <table>
        <thead>
            <tr>
                <th>Item</th>
                <th>&nbsp;</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="item in itens">
                <td>{{item}}</td>
                <td><a href="javascript:;" ng-click="excluir(item)">excluir</a></td>
            </tr>

        </tbody>
    </table>
    <div>{{msg}}</div>
</body>

 

É por aqui que finalizo meu estudo inicial sobre o Angular. Espero nos próximos post destacar o uso de templates, criação de diretivas próprias e AJAX com o AngularJS.

 

Referencial utilizado

  • AngularJS Succinctly [https://www.syncfusion.com/resources/techportal/ebooks]
  • Site Oficial [angularjs.org]
  • Ultimate guide to learning AngularJS in one day [http://toddmotto.com/ultimate-guide-to-learning-angular-js-in-one-day/]
  • AngularJS Tutorial [http://www.w3schools.com/angular/default.asp]