angularjs - podstawy

25
AngularJS Podstawy Wojciech Panek - Tech Lead, Apptension www.apptension.com

Upload: apptension

Post on 14-Apr-2017

738 views

Category:

Software


0 download

TRANSCRIPT

AngularJSPodstawy

Wojciech Panek - Tech Lead, Apptension

www.apptension.com

https://bitbucket.org/WojtekPanek/akaicountries

Cechy AngularJS

• Framework MVC/MVVM

• Dodatkowe atrybuty HTML

• Modele w postaci POJO (Plain Old Javascript

Object)

• Zestaw komponentów ułatwiających organizację

projektu

• Two-way Data Binding

• Dirty Checking

• Zbudowany z wykorzystaniem jQuery

• Duża popularność i wsparcie społeczności

Komponenty

Komponenty - Module

• Pozwala na grupowanie

• Zarządzanie Dependency Injection

• Konfiguracja

Komponenty - Modulevar application = angular.module('countriesApp', [ 'ui.router']);

application.config(['$locationProvider', '$stateProvider', '$urlRouterProvider', function($locationProvider, $stateProvider, $urlRouterProvider){

$locationProvider.hashPrefix('');

$stateProvider.state('countryList', { url: "/", templateUrl: "app/view/country-list.html" });

$stateProvider.state('countryView', { url: "/:name", templateUrl: "app/view/country-view.html" });

$urlRouterProvider.otherwise('/');}]);

Komponenty - Module<html data-ng-app="countriesApp">

<head lang="en">

<meta charset="UTF-8">

<title>AKAI Countries</title>

</head>

<body>

<div data-ui-view></div>

</body>

</html>

Komponenty - Controller

• Dostarcza dane widokom ($scope)

• Zawiera logikę widoków

• Nie powinien manipulować drzewem DOM

• Przypisywany widokom przy pomocy atrybutu

HTML ng-controller

Komponenty - Controllerapplication.controller('countryListController', ['$scope', 'countryService', function($scope, countryService){ $scope.countries = []; $scope.loadingCountries = true;

$scope.countryModel = { name: "", symbol: "" };

countryService.getList().then(function(list){ $scope.countries = list; $scope.loadingCountries = false; });

$scope.addCountry = function() { $scope.countries.push($scope.countryModel); $scope.countryModel = { name: "", symbol: "" } }

}]);

Komponenty - View

• Zapisywany w języku HTML rozszerzonym o dodatkowe atrybuty

• Ma dostęp do wszystkich elementów $scope• Dodatkowe atrybuty:

– ng-if– ng-show/ng-hide– ng-click– ng-repeat– ng-model– ng-class– ng-style– ng-src– ng-attr-{{ }}

Komponenty - View

<div data-ng-controller="countryListController"> <data-loader data-is-loading="loadingCountries"> <div> <label for="country-name">Name:</label> <input type="text" data-ng-model="countryModel.name" name="CountryName" id="country-name" /> </div> <div> <label for="country-symbol">Symbol:</label> <input type="text" data-ng-model="countryModel.symbol" name="CountrySymbol" id="country-symbol" /> </div> <div> <button data-ng-click="addCountry()">Add</button> </div> <hr> <div data-ng-repeat="country in countries track by $index"> <span> {{ country.name }} </span> <span> {{ country.symbol | countryCode }} </span> <a data-ui-sref="countryView({ name: country.name })"> view </a> </div> </data-loader></div>

Komponenty - Service

• Oparty o wzorzec projektowy Singleton• Może zostać wstrzyknięty w dowolne miejsce aplikacji przy

pomocy Dependency Injection• Często wykorzystywany do implementacji warstwy pobierającej

dane• Może zostać wykorzystany do implementacji warstwy Modeli• Predefiniowane serwisy:

– $http– $window– $q

Komponenty - Service

application.service('countryService', ['$http', '$q', function ($http, $q) {

this.getList = function () { var deferred = $q.defer();

$http.get('https://restcountries.eu/rest/v1/all').success(function (data) { var result = []; for (var i = 0; i < data.length; i++) { result.push({ name: data[i].name, symbol: data[i].alpha2Code }); } deferred.resolve(result); });

return deferred.promise; };

}]);

Komponenty - Factory

• Działanie i zastosowanie identyczne jak Service• Zwraca wynik funkcji zamiast instancji funkcji

Komponenty - Factory

application.factory('countryFactory', ['$http', '$q', function ($http, $q) { return { getList: function() { var deferred = $q.defer();

$http.get('https://restcountries.eu/rest/v1/all').success(function (data) { var result = []; for (var i = 0; i < data.length; i++) { result.push({ name: data[i].name, symbol: data[i].alpha2Code }); } deferred.resolve(result); });

return deferred.promise;

} };}]);

Komponenty - Directive

• Komponent interfejsu użytkownika przeznaczony do wielokrotnego użytku

• Nie powinien zawierać logiki biznesowej• Może manipulować drzewem DOM• Można do niego przekazać parametry:

– =– @– &

• Często używany do inicjalizacji bibliotek jQuery• Częsty powód wycieków pamięci

Komponenty - Directiveapplication.directive('loader', [ function(){ return { restrict: 'AE', replace: true, transclude: true, templateUrl: 'app/directive/loader/loader.html', scope: { isLoading: '=' }, link: function($scope, element) { var scale = 10; var negative = true;

$scope.animation = setInterval(function(){ angular.element(element).find(".loader").css('transform', 'scale(' + scale/10 + ')'); if(negative) scale -= 1; else scale += 1; if(scale == 0 || scale == 10) negative = !negative; }, 50);

$scope.$on('$destroy', function() { clearInterval($scope.animation); }); } } }]);

Komponenty - Filter

• Pozwala na manipulację danymi wejściowymi• Nie powinien zawierać logiki biznesowej• Domyślnie dostępny w widokach• Pozwala na przetwarzanie strumieniowe przy pomocy operatora |• Predefiniowane filtry:

– orderBy– filter– date– currency

Komponenty - Filter

application.filter('countryCode', function() {

return function(input) {

return '[' + input + ']'

};

});

Zagrożenia i Problemy

Zagrożenia i Problemy

• Nauka AngularJS nie jest prosta• Skalowalność i wydajność aplikacji• Czytelność struktury projektu• Wycieki pamięci• Ograniczone narzędzia do pisania testów (Protractor)• Pokusa używania jQuery• SEO• AngularJS 2.0

Biblioteki

Biblioteki

• ui-router• angular-bootstrap/angular-foundation• angular-ui• angular-translate• ngResource

Narzędzia

Dziękuję za uwagę