frontend for the win

Post on 25-Dec-2014

239 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

FRONTEND FOR THE WIN!Антон Плешивцев, aviasales.ru

МЕТАПОИСК

МЕТАПОИСК

МЕТАПОИСК

МЕТАПОИСК

МЕТАПОИСК

LEGACY

• кастомное решение

• 10К строк кода без тестов

• виджет-ориентированная архитектура

ЖИДКОЕ ПРИЛОЖЕНИЕ

Поисковая формаПоиск

Выдача

Билеты

ФильтрыСостояние

Агенства

Фидбек

История

Календарь

INTERFACE

NEW AGE

• AngularJS

• 3K строк кода

• 80% покрытие тестами

СТРУКТУРА

СТРУКТУРАПоисковая форма

Билеты Фильтры

СТРУКТУРАПоисковая форма

Билеты Фильтры

Форма История поисков

Календарь

Отели

Билеты

Цена

Время

Вылет

ВЗАИМОДЕЙСТВИЕ ЧАСТЕЙ

ВЗАИМОДЕЙСТВИЕ

Билеты

Календарь

Отели

Билеты Фильтры

Цена

Время

Вылет

?

ВЗАИМОДЕЙСТВИЕ

Билеты

Календарь

Отели

Билеты Фильтры

Цена

Время

Вылет

service

ВЗАИМОДЕЙСТВИЕ

Билеты Фильтры

Календарь

Отели

Билеты

Цена

Время

Вылет

«Выдача с фильтрами»

МОДУЛИ

MODULE PATTERNvar testModule = (function () { ! var counter = 0; ! return { ! incrementCounter: function () { return counter++; }, ! resetCounter: function () { console.log( "counter value prior to reset: " + counter ); counter = 0; } }; !})();

AMD MODULE

//Calling define with a dependency array and a factory function define(['dep1', 'dep2'], function (dep1, dep2) { ! //Define the module value by returning a value. return function () {}; });

DEPENDENCY INJECTION

function MyController($scope, greeter) { ! $scope.test = true; ! $scope.check = function(){ greeter.check($scope.test); }; !}

Ядро

Ядро

Форма поиска Выдача

Ядро

Форма поиска Выдача

Форма История Билеты Фильтры

Ядро

Форма поиска Выдача

Форма История Билеты Фильтры

Поиск

Календарь Отели Выдача

Цена Время

Ядро

Форма поиска Выдача

Форма История Билеты Фильтры

Поиск

Календарь Отели Выдача

Цена Время

Ядро

Форма поиска Выдача

Форма История Билеты Фильтры

Поиск

Календарь Отели Выдача

Цена Время

у

Выдача

Билеты Фильтры

{ filters: {} tickets: [] }

{ tickets: [] filters: {} sort: function(){…} }

{ reset: function(){…} filters: {} tickets: [] }

Выдача Цена{ sorting: ‘price’ tickets: [] filters: {} sort: function(){…} }

{ visible: [1000, 10 000] reset: function(){} filters: {} tickets: [] }

Выдача

Билеты Фильтры

{ filters: {} tickets: [] }

{ tickets: [] filters: {} sort: function(){…} }

{ reset: function(){…} filters: {} tickets: [] }

Выдача Цена{ sorting: ‘price’ tickets: [] filters: {} sort: function(){…} }

{ visible: [1000, 10 000] reset: function(){} filters: {} tickets: [] }

Выдача

Билеты Фильтры

Выдача Цена$scope.filters.price = [1000, 15000]

Выдача

Билеты Фильтры

Выдача Цена

$scope.filters.price = [1000, 15000]

$scope.filters.price = [1000, 15000]

Выдача

Билеты Фильтры

Выдача Цена$scope.filters.price = [1000, 15000]

$scope.filters.price = [1000, 15000]

onchange(‘filters.price’, function(){ update_tickets(); })

PITFALL

PITFALLВыдача

Фильтры

Цена

$scope.filters = { price: [100, 10000], duration: [3600, 84600], … }

BEFOREВыдача

Фильтры

Цена $scope.filters

$scope.filters

$scope.filters

AFTERВыдача

Фильтры

Цена $scope.filters

$scope.filters

$scope.filters

TEMPLATES

UNOBTRUSIVENANO("templates.searches.tickets.widgets.proposals", function(NANO){ return NANO.templates(‘ticket.html’, { "@data-ticket-id": "ticket.id", "@data-source": "source", ".ticket_proposal": { "gate<-proposals": { ".gate_name": "gate.name", ".gate_select_button a@href": "gate.url", ".gate_select_button a@data-gate": "gate.id", ".gate_price": "gate.price", ".gate_payment_methods .payment_method": { "method<-gate.payment_methods": { "@class+": " #{method}" } } } } }); });

DECLARATIVE

<li class="proposal-carousel" ng-repeat="proposal in ticket.proposals_for_carousel()"> <a class="agency_offer" ng-click="buy_ticket(ticket, proposal)"></a> <span>{{ proposal.name() | cut:15 }}</span> <span class="price"> <span>{{ proposal.price() | current_price:search.currency }}</span> </span> </li>

UNOBTRUSIVElayout.find(".yes").bind("click", function(){ self.toggle(layout, "yes"); }); layout.find(".no").bind("click", function(){ self.toggle(layout, "no"); }); layout.find("#new_feedback").submit(function(){ return self._submit(); });

<form class="feedback"> <div class="yes">Да</div> <div class="no">Нет</div> ... </form>

+

DECLARATIVE<form class="feedback" ng-submit="submit()"> <div class="yes" ng-click='success(true)'>Да</div> <div class="no" ng-click='success(false)'>Нет</div> ... </form>

ИТОГИ

COMPOSITE ARCHITECTURE IS POWERFUL

PROTOTYPE INHERITANCE IS GOOD

DECLARATIVE ALWAYS BETTER THEN IMPERATIVE

ANGULARJS IS BETTER THAN ANYTHING ELSE

ABOUT

АНТОН ПЛЕШИВЦЕВ !twitter.com/allaud github.com/allaud https://www.facebook.com/ant.pl.3 !aviasales.ru

top related