Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
1
Realizacja Aplikacji Internetowych
JavaScript
2
W trakcie ogladania tego slajdu (2-4min)
Oczekiwanie na zwrot różnych treści (głównie w tradycyjnych witrynach) zajmuje na świecie ~ osobo-minut to oznacza 66 osobo-lat albo np. 86 lotów na Marsa (wg. czasów np. lądownika Curiosity)
3
Tradycyjne strony Strona jest kompletowana (markup+dane) po stronie serwerowej Struktura DOM-a jest w zasadzie okreslona w momencie wysyłki z serwera Strona może zawierać javascript dla dodania efektów, dynamiki, formatowania, zmiany layout-u dla różnych rodzajów urzadzeń Historia, uprawnienia itd. mają naturalne odbicie w URL-ach
4
SPA Markup (mockup) HTML może być ładowany z bez/z małą ilościa danych
Dane są doładowywane asynchronicznie Brak wielokrotnego przesyłania redundantnych elementów (tagi/DOM/skrypty) Przeniesienie cześci ciężaru renderowania na stronę kliencką Mniejsze obciążenie łączy/serwerów Brak migania/zamrażania strony Wrażenie pracy z resoponsywną aplikacją
5
SPA vs strona serwerowa
Przy SPA serwer odpowiada za przesłanie inicjalnego mockup-u strony (definicji) ew. wypełnionej wstępnie danymi Dane: formaty natywne HTML, obrazki lub JSon XML Podejście hybrydowe Backend vs API
6
Rozwiązania klienckie
Silverlight Flash/Flex HTML 5 + CSS 3 Javascript CofeeScript, Dart, TypeScript GWT (java 2 javascript) Traceur (google: kompilator javascript next 2 javascript) Ecma Harmony / Narcisius (jw) Script# (c# 2 javascript) Pyjamas (python 2 javascript)
7
Javascript i biblioteki klienckie
Biblioteki operujące na DOOM JQuery, Prototype, MooTools Frameworki: Yui, Sencha ExtJS, Dojo, Knockout, EmberJS, Angular, Aurelia, Meteor BackBone ReactJS Bootstrap CSS, Less, Sass
8
Narzędzia Debugowanie, profiling: Pakiety, komendy
FireBug, Chrome Developer Tools, IE Inspector / WebDeveloper Fiddler Pakiety, komendy npm, jspm.io, Bower, Grunt Testy jednostkowe i akceptacyjne Junit Jasmine Automatyczne uruchamianie testów: Selenium Headless browsers PantomJS Zombi+NodeJs, ENVJS. + Rhino engine
9
Realizacja Aplikacji Internetowych
TESTOWANIE
10
Testowanie Jakieś testy są potrzebne … Testy jednostkowe
Testy integracyjne Testy akceptacyjne lub end-to-end
11
Środowisko Framework Narzędzia dodatkowe FireUnit
Środowisko uruchomieniowe Przeglądarka uruchamiana ręcznie Selenium + przeglądarka Na serwerze: PhantomJS (SlimerJS,CasperJS…) Node.js + Chimera | Karma rhino + env.js,
12
Framework QUnit (używany np. przez wiele plug-inów JQuery)
module('calculator'); test('add numbers', function() { var calc = new Calculator(); equals(4, calc.add(2, 2)); })
13
Framework Jasmine (BDD, hierarchiczna definicja setup-ów)
describe('panda',function(){ it('is happy',function(){ expect(panda).toBe('happy'); });
14
Framework Mocha (BDD, hierarchiczna definicja setup-ów, pozwala używać różnych assert libraries, raportuje wolne testy przy t. asynchr., coverrage) describe('panda',function(){ it('is happy',function(){ assert.equal('happy',panda.state); expect(panda).toBe('happy'); });
15
Framework Screw.Unit JSSpec
describe("Calculator", function() { it("should add numbers", function() { var calc = new Calculator(); expect(calc.add(2, 2)).to(equal, 4); }); }); JSSpec describe("Calculator", function() { with(this) { it("should add numbers", function() { var calc = new Calculator(); calc.add(2, 2).should(equal(4)); }); }});
16
Framework jsUnitTest jsUnitTest + jShoulda
new Test.Unit.Runner({ testCalculatorAdd: function() { with (this) { var calc = new Calculator(); assertEqual(4, calc.add(2, 2)); }} }); jsUnitTest + jShoulda context('Calculator', { should('add numbers', function() { with (this) { var calc = new Calculator(); assertEqual(4, calc.add(2, 2)); }})
17
Framework I wiele innych m.in
Unittest, jsAssertUnit, YUItest, Qooxdoo, JSUnit, JSUnit , Crosscheck, Ecmaunit, Dojo Objective Harness, FireUnit, Qunit, RhinoUnit, JSpec
18
Tools Smoke Amok MockMe
new Smoke.Stub(Calculator, 'add').and_return(5); Smoke.Mock(Calculator).should_receive('add').at_least('once') .with_arguments(2, 2).and_return(5); Amok var mock = amok.mock(Calculator); mock.should_receive('add').with_args(2, Number) .times(1).and_return(5); MockMe mock(Calculator).andDo(function() { SomethingThatUsesCalculator.calculate("2 + 2"); verify(Calculator.add)(2, 2); });
19
Tools qMock Jack Interesujace: JSMockito, Sinon.js, Mock.js
var mock = new Mock(); mock.expects(1).method('add').withArguments(2, 2).andReturn(5); Jack jack.expect("Calculator.add").exactly("1 time") .withArguments(2, 2).mock(function() { … return sth; }) jack.create("mock", ['add', 'substract']); .whereArgument(0).isOneOf(2, 3, 4); Interesujace: JSMockito, Sinon.js, Mock.js
20
Istotne uwagi Izolacja od drzewa DOM i globalnych odwołań do obiektów
Lokalne referencje do używanych obiektów Rozluznienie połączeń miedzy obiektami Mozliwość stosowanania wzorca obserwator (event) Stosowanie broker event (serviceBus) do komunikacji
21
Pokrycie kodu testami JSCoverage Istambul …
22
Realizacja Aplikacji Internetowych
JQuery
23
JQuery Silny model selekcji
Wsparcie dla typowych akcji np. ustawienie obsługi zdarzenia, dodanie, usunięcie klasy stylu itd. Gotowe rozwiazania typowych problemów Rozszerzalny model - wtyczki Dużo gotowych wtyczek Testowalny
24
JQuery Problem: wyszukiwanie elementów na stronie np:for ( var (i in document.getElementsByTagName("p") ) { i.onclick = function(event) { alert("Hello!"); } } JQuery: $("p").click(function(event){ alert("Hello!!"); }
25
Jquery – Referencjonowanie
<script src=" </script> <script> // Standard. jQuery $ jQuery(document).ready( function () { alert('DOM is ready!'); }); // Shortcut, but same thing as above. jQuery( function () { alert('No really, the DOM is ready!'); }); // Shortcut with fail-safe usage of $ jQuery(function($) {alert('Seriously its ready!'); });
26
JQuery Problem: wyszukiwanie elementów na stronie np:for ( var (i in document.getElementsByTagName("p") ) { i.onclick = function(event) { alert("Hello!"); } } JQuery: $("p").click(function(event){ alert("Hello!!"); }
27
JQuery Selektor zwraca kolekcję obiektów DOM "owiniętych" w obiekty JQuery (dodatkowe metody) Pojedynczy obiekt można owinac stosujac $ np. $(this) Kolekcję można ją zapamiętać i wyłuskać z niej referencje do poszczególnych elementów var jqlinki = $("a"); var pierwszy_link = linki[0]; Kolekcję można też sprowadzic do tablicy obiektów DOM var jqlinki = $("a").get();
28
JQuery - selektory Selektory zwracają kolekcję elementów JQuery opakowujących elementy DOM: $("*") – wszystko $("a") - po nazwie tagu $('#myDivId') - po id $('.myCssClass'), $(‘a.myCssClass')- po klasie CSS $("[id]") – po atrybucie $("[id=wartosc]") – po wartości atrybutu Np. $('div').each( function() { alert($(this).html(); });
29
JQuery – selektory strukturalne
$ (“selektor1, selektor2, selektorN”) $("p,a,div,code.bold") $("rodzic > dziecko") $(„p>a") $("przodek potomek") $("p a.bold") $ (“poprzedni+nastepny”) $ (“label.MyLabelClass + input”) $ (“poprzedni ~ cale_rodzenstwo”) $ (“h3 ~ p”)
30
JQuery - atrybuty $("[id]") $("p[id][name]")
$("[id=wartosc]") $("input[name='newsletter']") $("[id~=slowo]") $("input[name~='test']") $("[id|=poczatek_do_kreski_lub_rowny]") $("a[hreflang|='en']") $("[id*=podciag]") $("input[name~='xx']") $("[id^=poczatek]") $("input[name^='news']") $("[id$=koniec]") $("input[name^=letter']")
31
JQuery - selektory Selektory można łaczyć i dodawać
$("a.myCssClass, '#myDivId>a")
32
JQuery – modyfikatory selekcji
:animated, :checked, :disabled :enabled, :empty, :hidden, :visible, :selected :file, :checkbox, :button, :header, :password, :radio, :reset, :submit, :text :even, :odd, :first, :first-child, :last, :last-child, :parent :contains() $("div:contains('John')") :has() $("div:has('p')") :not(sektor) $("input:not(:checked) + span") :eq(), :lt(), :gt() $("td:eq(2)")
33
JQuery – filtry .eq(), .first(), .last(), .slice(od,[do]) $('li').eq(2) $('li').eq(-1) $('li').slice(3,-2) .filter(selector), filter(function) $('li').filter(':even') $('li').filter(function(index) { return index % 3 == 2; }) .has(selektor_potomka), .has(DOM_element_potomny) $('li').has('ul') .not(selektor), not(DOM_elementy), not(function(index)) $('li').not(':even') $("p").not( $("#selected")[0] )
34
JQuery – pobieranie zawartości
.get([pozycja]) - pobieranie elementów Dom $("a").get() .html() $('div.demo-container').html(); $( "#myDiv p:first" ) .html( "New <strong>first</strong> paragraph!" ); .length, size() var n = $("div").length; .val() $('select.foo option:selected').val() .attr() var title = $("em").attr("title"); $("em").attr("title“,”new title”);
35
JQuery – trawersowanie drzewa
.find(), .end() – kończy ostatnie find $("p").find("a") .siblings(), .children(), .contents(), .closest(), .next(), .prev(), .parent(), .parents() .prevAll(), .nextAll(), .andSelf() $("div:last").prevAll(".myClass") .nextUntil(), .parentsUntil(), .prevUntil() #("#term-2").nextUntil("dt") .offsetParent() – pozycja na ekranie .add() $('li').add('p')
36
JQuery – ZMIANY .replaceAll(co_zastapic_selekcja) $("<b>Paragraph.</b>").replaceAll("p") .replaceWith(noweElementy), replaceWith(funkcja), $('.second').replaceWith( "<h2>New heading</h2>"); $('.third').replaceWith($('.first'));
37
JQuery – transformacje
.map( callback(this, index) ) var oneBased = $.map([0,1,2,3,4], function(value){return value+1;}); var ids = $(':checkbox').map(function() { return this.id; })
38
JQuery – predykaty .hasClass() $('#mydiv').hasClass('foo')
.is() $(this).is(".blue,.red")
39
JQuery – modyfikacje .addClass(), removeClass() $('p').addClass('myClass yourClass'); .toggleClass( className ), .toggleClass( className, switch ), .toggleClass( function(index, class), [ switch ] ) $("p").click(function () { $(this).toggleClass("highlight"); }); .removeAttr() $(this).next().removeAttr("disabled") .css(), .attr(), .val() $(‘p’). css( { fontSize: "100px", color: "red“ } )
40
JQuery – zdarzenia .error(), .resize(), .scroll() $('#book').error(function() { alert('Handler called.') }); .load()*, .ready(), .unload()* .blur(), .change(), .focus(), .select(), .submit() $('form').submit(function() { alert('Handler for .submit() called.'); return false; }); .focusin(), .focusout(), .keydown(), .keypress(), .keyup() .hover(), .mousedown(), .mouseenter(), .mouseleave(), .mousemove(), .mouseout(), .mouseover(), .mouseup(), .click(), .dblclick(), on() $('#target').click( function() { alert(‘click handler called.'); } ); * - deprecated -> on(“load”…
41
JQuery – efekty .hide(), show() $('p').addClass('myClass yourClass');
.focus() .slideDown(), .slideToggle(), .slideUp() ("div").slideDown("slow"); .fadeIn(), .fadeOut(), .fadeTo() $("div:hidden:first").fadeIn("slow"); .animate(), .stop(), .delay(), jQuery.fx.off $('#book').animate({ width: ['toggle', 'swing'], height: ['toggle', 'linear'], opacity: 'toggle' }, 5000, function() { // Animation complete. }); );
42
JQuery – Ajax load(), jQuery.get(), jQuery.getJSON(), jQuery.getScript(), jQuery.post() $.get("test.cgi", { name: "John", time: "2pm" }, function(data){ alert("Data Loaded: " + data); }); $('#result').load('ajax/test.html', function() { alert('Load was performed.'); }); jQuery.ajax(), jQuery.ajaxSetup(), $.ajax({ type: 'POST', url: url, data: data, success: success, dataType: dataType }); .ajaxComplete(), .ajaxError(), .ajaxSend(), .ajaxStart(), .ajaxStop(), .ajaxSuccess(), . jQuery.param(), .serialize(), .serializeArray()
43
JQuery – Różne .clone(), .append(), appendTo(), .prepend(), .prependTo(), text(), html() $('h2').appendTo($('.container')); $("p").text("<b>Some</b> new text."); .unwrap(), .wrap(), .wrapAll(), .wrapInner() $("span").wrap("<div><p><em><b></b></em></p></div>"); $("span").wrapAll("<div></div>") .replaceAll(), .replaceWith() $('<h2>New heading</h2>').replaceAll('.inner'); $(‘<div/>’).replaceWith(‘<p></p>’); .detach(), .empty(), .remove() $('.hello').empty();
44
JQuery – Literatura Materiały: Ksiązki Doc do VS jquery.com
“JQuery in Action” “Learning jQuery” “jQuery UI” “jQuery Cookbook” Doc do VS
45
Realizacja Aplikacji Internetowych
Ext-Js
46
Ext-JS (Sencha, Aptana)
Ext-core – skrócona wersja – bez frameworka UI Ext-all – pełna wersja z kontrolkami Jako selektora DOM może korzystać z GWT, jQuery, DOM, YUI Framework: Komercyjny Komercyjny: Ext builder
47
Ext - core Uruchamianie skryptów na DOM Szukanie elementow po id
Ext.onReady(function() { ... }); Szukanie elementow po id var el=Ext.get('myElementId'); el.addClass('error'); Lekkie "nietrwałe" referencje Ext.fly('elId').hide(); Szukanie elementow Ext.query('div:nth-child(2)'). findParent('div');
48
Ext - core Zdarzenia Animacje
Ext.fly('myEl').on('click', function(e, t) { alert("clicked!!!"); }); Animacje var el=Ext.get('myElementId'); el.slideOut('t', { easing: 'easeOut', duration: .5, remove: false, useDisplay: false });
49
Ext - "klasy" Dziedziczenie
Person = Ext.extend(Object, { constructor: function(first, last){ this.firstName = first; this.lastName = last; } getName: function(){ return this.firstName + ' ' + this.lastName; } }); var p1 = new Person('John', 'Smith');
50
Ext - narzędzia Odwołania do klasy bazowej Przestrzenie nazw
MyClass = Ext.extend(Object, { constructor: function(config){ MyClass.constructor.call(this, config); }, foo: function(){ ... } }); Przestrzenie nazw Ext.namespace( 'MyCompany', 'MyCompany.Application'); Ext.namespace('MyCompany.Application');
51
Ext – wzorzec obserwator
var MyClass = Ext.extend(Ext.util.Observable, { constructor: function(config){ this.addEvents('datachanged'); // event MyClass.constructor.call(this, config); }, update: function(){ // jakies transformacje // Przy "odpaleniu" zdarzenia mozemy okreslic // parametry ktore maja byc przekazane this.fireEvent('datachanged', this, this.data.length); } }); // Subskrypcja eventu var c = new MyClass(); c.on('datachanged', function(obj, num){ /* obsluga.*/ });
52
Ext - DOM Modyfikacja DOMa createHtml (przestarzale), markup
insertHtml,insertBefore,insertAfter, insertFirst, append, overwrite Ext.DomHelper.append(document.body, { id: 'my-div', cn: [{ tag: 'a', href: ' html: 'My Link', target: '_blank' }] });
53
Ext - DOM Skryptowanie: var myEl = document.createElement('a');
myEl.href = ' myEl.innerHTML = 'My Link'; myEl.setAttribute('target', '_blank'); var myDiv = document.createElement('div'); myDiv.id = 'my-div'; myDiv.appendChild(myEl); document.body.appendChild(myDiv);
54
Ext - AJAX Globalne handlery: Typowe wołanie:
Ext.Ajax.on('beforerequest', this.showSpinner, this); Ext.Ajax.on('requestcomplete', this.hideSpinner, this); Ext.Ajax.on('requestexception', this.hideSpinner, this); Typowe wołanie: Ext.Ajax.request({ url: 'ajax_demo/sample.json', success: function(response, opts) { var obj = Ext.decode(response.responseText); console.dir(obj); }, failure: function(response, opts) { console.log('server-side failure with status code ' + response.status); }});
55
Ext - GUI ViewPort, Window Toolbar, Progresbar, TabPanel, Panel,
Editor, DataPicker, DataView Button, ButtonGroup
56
Ext - przykład Ext.onReady(function() { var item1 = new Ext.Panel({ title: 'Accordion Item 1', html: '<empty panel>', cls:'empty' }); var item2 = new Ext.Panel({ title: 'Accordion Item 2', html: '<empty panel>', cls:'empty' }); ... var accordion = new Ext.Panel({ renderTo: Ext.getBody(), // do elementu 'myDiv' margins:' ', split:true, width: 210, layout:'accordion', items: [item1, item2, item3, item4, item5] });
57
Ext - przykład Ext.onReady(function() { var item1 = new Ext.Panel({ }); var accordion = new Ext.Panel({ region:'west', margins:' ', split:true, width: 210, layout:'accordion', items: [item1, item2, item3, item4, item5] }); var viewport = new Ext.Viewport({ layout:'border', items:[ accordion, { region:'center', margins:' ', cls:'empty',bodyStyle:'background:#f1f1f1', html:'<br/><br/><empty center panel>' }] });
58
Ext – przykład: reużycie kontrolek
Ext.onReady(function() { MyPanel = extend(Ext.Panel, { title: 'Accordion Item 1', html: '<empty panel>', cls:'empty' }); ... var accordion = new Ext.Panel({ region:'west', margins:' ', split:true, width: 210, layout:'accordion', items: [ new MyPanel(), new MyPanel(), new MyPanel(), new MyPanel(), new MyPanel() ] });
59
Ext-GUI Przykłady: Lauout Drag&Drop Form Desktop
60
Ext-GUI Rozluznienie powiazań m. Komponentami Lokalne referencje
Obserwator Mediator: publish/subscribe Simplebus Ext.bus
61
Realizacja Aplikacji Internetowych
AngularJS
62
Kompleksowy framework JS
“opinionated” Dwukierunkowy binding HTML jako szablon – deklaratywna składnia MVC - MVVM Dependency Injection Rozszerzalny Testowalny Dobrze współpracuje z JQuery, Bootstrap 2.0 NIEKOMPATYBILNY Z 1. (1.5 w. przejściowa)
63
Dyrektywy Atrybuty: <html ng-app="project"> Tagi
<ng-pluralize count="beerCount" when="beerForms"> <my-widget title=“My Widget">
64
Binding
65
Kontroler <div ng-controller="MyController"> <span class="My-"+{{getClass()}}> {{GeneralInfo}} </span> <ol ng-repeat="element in form.elementsToShow"> <li ng-show="element.visible">{{element.content}}</li> </ol> </div>
66
Kontroler angular.module('myApp', []) .controller('MyController', ['$scope', function($scope) { $scope.elementsToShow = [ {content:'aaa', exists:true}, {content:'bbb', exists:false}]; $scope.neneralInfo = "Info"; $scope.getClass = function() { if (..) return "claccSuffix"; }); }]);
67
Kontroler
71
Filtry (1.0) / potoki (2.0) {{ data | filter:options }}
{{ element.price | currency }} currency uppercase date:' h:mma dd/MM/yyyy‘ limitTo:8 ng-repeat="…|orderBy:'-content'"
72
Formatowanie ng-class/ ngClass (2.0) ng-show / [hidden]
<h3 ng-show="vm.favoriteHero"> <h3 [hidden]="!favoriteHero">
73
ng-pristine, ng-submitted ng-invalid, ng-valid ng-dirty
Formatowanie <a href ng-click="tab = 1"> ng-pristine, ng-submitted ng-invalid, ng-valid ng-dirty ng-scope, ng-isolate-scope ng-binding
74
Zdarzenia ng-submit / submit ng-init / init
ng-click (1.0) / click (2.0) <a href ng-click="tab = 1"> <button (click)="toggleImage()"> ng-submit / submit ng-init / init
75
Dane i binding binding {{GeneralInfo}} ng-repeat="todo in todos"
ngFor (2.0) <input type="checkbox" ngModel (2.0)
76
Modularyzacja ng-include="'sub-page.html‘"
ng-controller= "MyController as ctrl« <my-directive></my-directive > <span my-attribute></span>
77
Custom element <my-directive>
app.directive('myDirective', function(){ return { restrict: 'E', templateUrl: 'myTemlate.html', }; }); Element Attribute Class
78
Custom element <my-directive>
app.directive('myDirective', function(){ return { restrict: 'E', templateUrl: 'myTemlate.html', controller: function(){...}, controllerAs: 'ctrl' }; }); Element Attribute Class
79
Modularyzacja ng-include="'sub-page.html‘"
ng-controller= "MyController as ctrl« <my-directive></my-directive > <span my-attribute></span> var myModule = angular.module('myModule', []);
80
Serwisy, DI app.controller('MyController', ['$http', $log, function($http, $log){ }]); Serwisy
81
Serwisy, DI app.controller('MyController', ['$http', $log, function($http, $log){ }]); Leniwa inicjalizacja Model singleton Standardowe s.: $anchorScroll, $animate, $cacheFactory, $compile, $controller, $document, $exceptionHandler, $filter, $http, $httpBackend, $interpolate, $interval, $locale, $location, $log, $parse, $q, $rootElement, $rootScope, $sce, $sceDelegate, $templateCache, $templateRequest, $timeout, $window Serwisy
82
Własny serwis var myModule = angular.module('myModule', []); myModule.factory('myService', function() { var serviceInstance; // inicjalizacja return serviceInstance; }); myModule.factory('myServiceWithDep', [$log, myService, function($log, mySrvc){ return ...;
83
Wykorzystanie DI – serwis locator
var di = angular.injector(['myModule', 'ng']); var split = di.get('splitter'); var contr = di.instantiate('MyController'); Pot. wykorzystanie cache
84
Własne filtry {{name | reverse}}
angular.module('myApp', []) .filter('reverse', function() { return function(input, uppercase) { input = input || ''; var out = ""; for (var i = 0; i < input.length; i++) { out = input.charAt(i) + out; } // conditional based on optional argument if (uppercase) { out = out.toUpperCase(); return out; }; })
85
Angular - kontekst $scope może być zagnieżdzony
może odwołać sie do rodzica i odczytać jego wartości nie może odczytać wartości dzieci
86
Angular - wady Relatywnie drobne błedy potrafią spowodować niedziałanie całej strony Wolno działa pod starszymi przeglądarkami IE7, IE8 Pot. wolny dla skomplikowanych stron Trudno zrzumieć niektóre interakcje Niektóre mechanizmy są trudne np uaktualnianie scope vs event loop vs binding
87
Realizacja Aplikacji Internetowych
ReactJS
88
ReactJS - jeszcze inne podejście
var Hello = React.createClass({displayName: 'Hello', render: function() { return React.createElement("div", null, "Hello ", this.props.name); } }); ReactDOM.render( React.createElement(Hello, {name: "World"}), document.getElementById('container') );
89
ReactJS - jeszcze inne podejście
Skupia się na izolacji komponentów (za to kod html jest pomieszany z kodem js). Unika zarządzania stanem – przy każdej zmianie cały widok jest renderowany ponownie (w przeglądarce lub na serwerze) Koncepcja funkcyjna: wyświetlenie strony polega na wyrenderowaniu html-a na podstawie stanu Modele sa zwykłymi obiektami js Jednokierunkowe wiązanie Szybki - asynchroniczne odświeżanie widoku (kolejka) może być bardziej efektywne niż natychmiastowe odświeżanie przy b. rozbudowanych aplikacjach
90
Realizacja Aplikacji Internetowych
CoffeeScript
91
Instalacja Node.js + coffee-script.js CoffeeSharp.zip
NUGet: Install-Package CoffeeSharp Coffee.exe CoffeeScriptHttpHandler.dll CoffeeSharp.dll Jurassic.dll
92
Motywacja Zwięzła składnia Redukcja szumu {} itd Dodatkowe możliwości
Poprawione problemy (==, var) Produkowany jest dobry kod Javascript Informacje Ksiazki: Screencast:
93
Podstawy Komentarz # Przypisanie – tworzy zmienna Abc =5 var Abc = 5
Bloki realizowane za pomoca wcięć if happy and knowsIt clapsHands() chaChaCha() else showIt() if (happy && knowsIt) { clapsHands(); chaChaCha(); } else { showIt();
94
Operatory Operatory CoffeeScript vs JavaScript is isnt not and or
true, yes, on false, no, off @, this of in, ? === !== ! && || true false this in Brak odpowiednika alert "I knew it!" if elvis? if (typeof elvis !== "undefined" && elvis !== null) alert("I knew it!");
95
Interpolacja zmiennych
Zmienne w " " podlegają interpolacji a w ' ' nie podlegają author = "Wittgenstein" quote = "A picture is a fact. -- #{ author }" sentence = "#{ 22 / 7 } is a decent approximation of π" var author, quote, sentence; author = "Wittgenstein"; quote = "A picture is a fact. -- " + author; sentence = "" + (22 / 7) + " is a decent approximation of π";
96
Wieloliniowe literały i komentarze blokowe
html = ''' <strong> cup of coffeescript </strong> ''' ### CoffeeScript Compiler v1.1.2 Released under the MIT License
97
Kaskadowe porównania cholesterol = 127
healthy = 200 > cholesterol > 60 var cholesterol, healthy; cholesterol = 127; healthy = (200 > cholesterol && cholesterol > 60);
98
Funkcje Składnia ala Ruby, zwraca wynik ostaniej instrukcji
Nawiasy przy wywołaniach można pomijać square(x) -> x*x test(x,y) -> a=5 x+y+a function square(x) { return x*x; } function test(x,y) { var a = 5; return x+y+5; } z = square 5 var z = square(5);
99
Funkcje i this Account = (customer, cart) -> @customer = customer
@cart = cart $('.shopping_cart').bind 'click', (event) -> var Account; var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; Account = function(customer, cart) { this.customer = customer; this.cart = cart; return $('.shopping_cart').bind('click', __bind(function(event) { return this.customer.purchase(this.cart); }, this)); };
100
Obiekty Składnia wymaga wcięć math = root: Math.sqrt square: square
cube: (x) -> x * square x math = { root: Math.sqrt, square: square, cube: function(x) { return x * square(x); } };
101
Wszystko jest wyrażeniem
grade = (student) -> if student.excellentWork "A+" else if student.okayStuff if student.triedHard then "B" else "B-" else "C" eldest = if 24 > 21 then "Liz" else "Ike" var eldest, grade; grade = function(student) { if (student.excellentWork) { return "A+"; } else if (student.okayStuff) { if (student.triedHard) { return "B"; } else { return "B-"; } return "C"; }; eldest = 24 > 21 ? "Liz" : "Ike";
102
Pętle for, while, until, Petle zwracają wartość
eat food for food in ['toast', 'cheese', 'wine'] var food, _i, _len, _ref; _ref = ['toast', 'cheese', 'wine']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { food = _ref[_i]; eat(food); }
103
Pętle Zwrot z petli mozna przypisac
cubes = (math.cube num for num in list) cubes = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = list.length; _i < _len; _i++) { num = list[_i]; _results.push(math.cube(num)); } return _results; })();
104
Przypisania wielokrotne
theBait = 1000 theSwitch = 0 [theBait, theSwitch] = [theSwitch, theBait] var theBait, theSwitch, _ref; theBait = 1000; theSwitch = 0; _ref = [theSwitch, theBait], theBait = _ref[0], theSwitch = _ref[1];
105
switch switch (day) { case "Tue": go(relax); break;
case "Thu": go(iceFishing); case "Fri": case "Sat": if (day === bingoDay) { go(bingo); go(dancing); } case "Sun": go(church); default: go(work); switch day when "Tue" then go relax when "Thu" then go iceFishing when "Fri", "Sat" if day is bingoDay go bingo go dancing when "Sun" then go church else go work
106
try/catch/finally try allHellBreaksLoose() try { allHellBreaksLoose();
catsAndDogsLivingTogether() catch error print error finally cleanUp() try { allHellBreaksLoose(); catsAndDogsLivingTogether(); } catch (error) { print(error); } finally { cleanUp(); }
107
Sklejanie tablic numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
copy = numbers[0..numbers.length] middle = copy[3..6] var copy, middle, numbers; numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; copy = numbers.slice(0, numbers.length); middle = copy.slice(3, 7);
108
Sklejanie tablic numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
var numbers, _ref; numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; [].splice.apply(numbers, [3, 4].concat(_ref = [-3, -4, -5, -6])), _ref;
109
Przypisania mogą dekomponowac struktury
var city, futurists, name, street, _ref, _ref2; futurists = { sculptor: "Umberto Boccioni", painter: "Vladimir Burliuk", poet: { name: "F.T. Marinetti", address: ["Via Roma 42R", "Bellagio, Italy 22021"] } }; _ref = futurists.poet, name = _ref.name, _ref2 = _ref.address, street = _ref2[0], city = _ref2[1]; futurists = sculptor: "Umberto Boccioni" painter: "Vladimir Burliuk" poet: name: "F.T. Marinetti" address: [ "Via Roma 42R" "Bellagio, Italy 22021" ] {poet: {name, address: [street, city]}} = futurists
110
Przypisania mogą dekomponowac zakresy
tag = "<impossible>" [open, contents..., close] = tag.split("") var close, contents, open, tag, _i, _ref; var __slice = Array.prototype.slice; tag = "<impossible>"; _ref = tag.split(""), open = _ref[0], contents = 3 <= _ref.length ? __slice.call(_ref, 1, _i = _ref.length - 1) : (_i = 1, []) , close = _ref[_i++];
111
Argumenty Funkcji gold = silver = rest = "unknown"
awardMedals = (first, second, others...) -> gold = first silver = second rest = others contenders = [ "Michael Phelps" "Liu Xiang" "Yao Ming" "Allyson Felix" "Shawn Johnson" "Roman Sebrle" "Guo Jingjing" "Tyson Gay" "Asafa Powell" "Usain Bolt" ] awardMedals contenders... var awardMedals, contenders, gold, rest, silver; var __slice = Array.prototype.slice; gold = silver = rest = "unknown"; awardMedals = function() { var first, others, second; first = arguments[0], second = arguments[1], others = 3 <= arguments.length ? __slice.call(arguments, 2) : []; gold = first; silver = second; return rest = others; }; contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"]; awardMedals.apply(null, contenders);
112
Klasy CoffeScript oferuje koncepcję klas
Klasy mają składnię zbliżoną do obiektów Wspierane jest dziedziczenie i odwołania do klas bazowych
113
class Animal constructor: -> move: (meters) -> + " moved #{meters}m." class Snake extends Animal move: -> alert "Slithering..." super 5 sam = new Snake "Sammy the Python" sam.move() class Horse extends Animal alert "Galloping..." super 45 tom = new Horse "Tommy the Palomino" tom.move()
114
var Animal, Horse, Snake, sam, tom;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; Animal = (function() { function Animal(name) { this.name = name; } Animal.prototype.move = function(meters) { return alert(this.name + (" moved " + meters + "m.")); return Animal; })();
115
Snake = (function() { __extends(Snake, Animal); function Snake() { Snake.__super__.constructor.apply(this, arguments); } Snake.prototype.move = function() { alert("Slithering..."); return Snake.__super__.move.call(this, 5); }; return Snake; })(); Horse = (function() { __extends(Horse, Animal); function Horse() { Horse.__super__.constructor.apply(this, arguments); } Horse.prototype.move = function() { alert("Galloping..."); return Horse.__super__.move.call(this, 45); return Horse; sam = new Snake("Sammy the Python"); tom = new Horse("Tommy the Palomino"); sam.move(); tom.move()
116
Realizacja Aplikacji Internetowych
Wygląd …
117
Wygląd czyli CSS to początek
Zerowanie stylów LESS, SASS Twitter BootStrap
118
Zerowanie stylów Problem: w poszczególnych przeglądarkach różne są domyślne wartości dla poszczególnych znaczników Minimum: * { padding: 0; margin: 0; } Podstawowy: * { vertical-align: baseline; font-weight: inherit; font-family: inherit; font-style: inherit; font-size: 100%; border: 0 none; outline: 0; padding: 0; margin: 0; } Zerujące CSS-y: Eric Meyer, Shaun Inmann, Chris Poteet
119
Zerowanie stylów Zalety: Piszemy od zera, a nie łatamy
Tylko wybrane (zdefiniowane) style będą dostępne Wiele rzeczy jest prostszych np. okreslamy padding I nie musimy werifikować czy przypadkiem marginnie jest gdzieś ustawiony Łatwiej opanować róznicew między przegladarkami
120
Zerowanie stylów Wady: Wieksza waga wytryny
Trzeba zdefiniować wszystko od początku = sporo pracy I tak nie załatwia wszystkich problemów kompatybilnościwych
121
Preprocesory CSS Najpopularniejsze: LESS, SASS
Pozwalają uzywać rozszerzeń np: Zagnieżdzanie reguł Zmienne Instrukcje warunkowe Funkcje Importowanie plików Mix-iny Wymagają dodatkowego kroku - kompilacji
122
Twitter - Bootstrap Pozwala szybko tworzyć strony z gotowych elementów
Dostępnych wiele gotowych rozwiązań/tematów 12 kolumnowy grid oparty na pixelach/procentach Reaktywny Wiele gotowych do użycia komponentów i wtyczek Wielo-platformowy: smartfony, przeglądarki
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.