knockout.js на примере 2ГИС-Онлайн

Post on 29-Nov-2014

1.525 Views

Category:

Documents

9 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

САЛЬНИКОВ СТАНИСЛАВ

KNOCKOUT.js НА ПРИМЕРЕ 2ГИС-ОНЛАЙН

WWW.2GIS.RU

Пользователь

2ГИС Онлайн

API Справочника

АРХИТЕКТУРА WEB-APP

АРХИТЕКТУРА CLIENT-SIDE APP

Пользователь

2ГИС Онлайн

API Транспорта

API пробок

API <Место для

вашего сервиса>

API Справочник

API Карт +1

WWW.2GIS.RU

DOM НА КЛИЕНТЕ

WWW.2GIS.RU

DOM НА КЛИЕНТЕ

var newDiv = document.createElement('div'); newDiv.className = 'my-class'; newDiv.id = 'my-id'; newDiv.innerHTML = 'Привет, мир!';

document.body.appendChild(newDiv);

Привет, мир!

WWW.2GIS.RU

WHERE IS

ШАБЛОНИЗАТОРЫ

jQueryTemplate

Mustache

Underscore.js

Шаблонизатор резига

Pure

WWW.2GIS.RUWWW.2GIS.RU

СОБЫТИЯ

.firmShort .firmFull

WWW.2GIS.RUWWW.2GIS.RU

#firmList

СОБЫТИЯ

$("#firmTemplate").tmpl(someData).appendTo("#firmList");

$('.firmShort').live({ click: function() { showFirmCard(this); } });

$('.firmFull').live({ click: function() { hideFirmCard(this); } });WWW.2GIS.RUWWW.2GIS.RU

WWW.2GIS.RUWWW.2GIS.RU

СОБЫТИЯ

KNOCKOUT

WWW.2GIS.RUWWW.2GIS.RU

ПОЧЕМУ KNOCKOUT?

Активно развивается

WWW.2GIS.RUWWW.2GIS.RU

● Активно развивается

ПОЧЕМУ KNOCKOUT?

Удобное разделение логики и шаблонов

WWW.2GIS.RUWWW.2GIS.RU

● Активно развивается● Удобное разделение логики и шаблонов

ПОЧЕМУ KNOCKOUT?

Функционален, есть декларативные биндинги

WWW.2GIS.RUWWW.2GIS.RU

● Активно развивается● Удобное разделение логики и шаблонов● Функционален, есть декларативные

биндинги

ПОЧЕМУ KNOCKOUT?

Низкий порог вхождения

WWW.2GIS.RUWWW.2GIS.RU

MVVM

View Model

ViewModel

UI Logic Business Logic

Application Logic

WWW.2GIS.RUWWW.2GIS.RU

MVVM

ViewModel

WWW.2GIS.RUWWW.2GIS.RU

Данные

Вспомогательные функции

Связывание данных с отображениемKO

KNOCKOUT

WWW.2GIS.RUWWW.2GIS.RU

<div> <span data-bind="text: what"></span>, <span data-bind="text: where"></span></div>

KNOCKOUT

WWW.2GIS.RUWWW.2GIS.RU

function vm() {this.what = ko.observable('');

}

KO.OBSERVABLE

WWW.2GIS.RUWWW.2GIS.RU

function vm() {this.what = ko.observable('');

}ko.applyBindings(new vm());

KO.OBSERVABLE

WWW.2GIS.RUWWW.2GIS.RU

function vm() {this.what = ko.observable('');

}ko.applyBindings(new vm());

vm.what(response.what);

<span data-bind="text: what"></span>

KO.OBSERVABLE

WWW.2GIS.RUWWW.2GIS.RU

МАССИВЫ

WWW.2GIS.RUWWW.2GIS.RU

response.result = [ { firmName = 'Завод №1', ... }, { firmName = 'Завод №2'; ... }]

МАССИВЫ

WWW.2GIS.RUWWW.2GIS.RU

function vm () {this.firms = ko.observableArray([]);

}...vm.firms(response.result);

<div data-bind="foreach: firms"><div data-bind="text: firmName"></div>

</div>

KO.OBSERVABLE_ARRAY

WWW.2GIS.RUWWW.2GIS.RU

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

<div> <span data-bind="text: what"></span>, <span data-bind="text: where"></span></div>

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

BINDINGS

- Текст и стиль блока

- Control flow

- Работа с формами

- Шаблонизация

- События

WWW.2GIS.RUWWW.2GIS.RU

- <место для ваших идей>

BINDINGS

.firmShort .firmFull

WWW.2GIS.RUWWW.2GIS.RU

#firmList

<div id="firmList" data-bind="foreach: firms"><div class="firmShort"

data-bind="visible: !isVisible"></div><div class="firmFull"

data-bind="visible: isVisible"></div></div>

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

data-bind="visible: isVisible,click: toggleVisibility"

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

data-bind="visible: isVisible,click: toggleVisibility"

toggleVisibility = function() { this.isVisible(!this.isVisible());}

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

ko.bindingHandlers['visible'] = { 'update': function (element, valueAccessor) { var value = ko.utils.unwrapObservable(valueAccessor()); var isCurrentlyVisible = !(element.style.display == "none"); if (value && !isCurrentlyVisible) element.style.display = ""; else if ((!value) && isCurrentlyVisible) element.style.display = "none"; }};

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

ko.bindingHandlers['animateVisible'] = { 'update': function (element, valueAccessor) { var value = ko.utils.unwrapObservable(valueAccessor()); var isCurrentlyVisible = !(element.style.display == "none"); var slideSpeed = 200; if (value && !isCurrentlyVisible) $(element).slideDown(slideSpeed, callback); else if ((!value) && isCurrentlyVisible) $(element).slideUp(slideSpeed, callback); }};

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

data-bind="animateVisible: isVisible,click: toggleVisibility"

toggleVisibility = function() { this.isVisible(!this.isVisible());}

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

<script type="text/my-tpl" id="firm-tpl"> // Put yor awesome template here!</script>

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

<script type="text/my-tpl" id="catalog-tpl"> <div data-bind="template: { name: 'firm-tpl', foreach: firms }"></div>

</script>

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

BINDING-CONTEXT

vm

vm.firms[n]

WWW.2GIS.RUWWW.2GIS.RU

context === $data

BINDING-CONTEXT

WWW.2GIS.RUWWW.2GIS.RU

context === $data$data === $context.$data

BINDING-CONTEXT

WWW.2GIS.RUWWW.2GIS.RU

BINDINGS

<div class="contacts" data-bind="template: { name: 'firm-tpl', data: $data }"> <!-- Some code--></div>

WWW.2GIS.RUWWW.2GIS.RU

BINDING CONTEXT

$context

$element

● $data● $parent● $parentContext● $root● $index

WWW.2GIS.RUWWW.2GIS.RU

function initBalloon (options) { map.createBalloon({ point: options.point; content: options.template }); }

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

function initBalloon (options) { map.createBalloon({ point: options.point; content: options.template });

var container = $('#balloonContent'); ko.applyBindingsToNode(container , vm);}

BINDINGS

WWW.2GIS.RUWWW.2GIS.RU

КОГДА МНОГО "ЕСЛИ"

WWW.2GIS.RUWWW.2GIS.RU

this.hidePreloader = ko.computed(function(){ return this.firmsLoad() && this.geoLoad();});

<span id="preloader" data-bind="visible: !hidePreloader"></span>

КОГДА МНОГО "ЕСЛИ"

WWW.2GIS.RUWWW.2GIS.RU

Не наблюдайте один computed внутри другого

KO.COMPUTED

WWW.2GIS.RUWWW.2GIS.RU

1. Не наблюдайте один computed внутри другого

KO.COMPUTED

Не меняйте observable внутри computed

WWW.2GIS.RUWWW.2GIS.RU

1. Не наблюдайте один computed внутри другого2. Не меняйте observable внутри computed

KO.COMPUTED

Используйте computed только там, где это необходимо

WWW.2GIS.RUWWW.2GIS.RU

PLUGINS

WWW.2GIS.RUWWW.2GIS.RU

PLUGINS

knockout.address

WWW.2GIS.RUWWW.2GIS.RU

PLUGINS

WWW.2GIS.RUWWW.2GIS.RU

PLUGINS

window.location vm.myObservable

WWW.2GIS.RUWWW.2GIS.RU

PLUGINS

window.location vm.myObservable

WWW.2GIS.RUWWW.2GIS.RU

ko.linkObservableToUrl(vm.history, 'history');

https://github.com/SteveSanderson/knockout/wiki/Plugins

PLUGINS

WWW.2GIS.RUWWW.2GIS.RU

БОЛЬШИЕ ПРОЕКТЫ

107 22 18

ObservableComputed Observable

Array

WWW.2GIS.RUWWW.2GIS.RU

Functions

БОЛЬШИЕ ПРОЕКТЫ

200+ 107 22 18

WWW.2GIS.RUWWW.2GIS.RU

БОЛЬШИЕ ПРОЕКТЫ

200+ 107

22

18

13WWW.2GIS.RUWWW.2GIS.RU

Namespace.ViewModelModules.ourModule = { _observables: { ourObservable: "", ourObservableArray: [], ourComputed: function(){} },

_initModule: function(){/*initCode*/},

someProperty: 100500,

someFunction: function(){/*fBody*/}}

БОЛЬШИЕ ПРОЕКТЫ

WWW.2GIS.RUWWW.2GIS.RU

Namespace.ViewModelModules.ourModule = { _observables: { ourObservable: "", ourObservableArray: [], ourComputed: function(){} },

_initModule: function(){/*initCode*/},

someProperty: 100500,

someFunction: function(){/*fBody*/}}

WWW.2GIS.RU

БОЛЬШИЕ ПРОЕКТЫ

150

WWW.2GIS.RUWWW.2GIS.RU

IDE

data-bind=" //очень много //кода //который выглядит //как одна сплошная строка"

WWW.2GIS.RUWWW.2GIS.RU

IDE

WWW.2GIS.RUWWW.2GIS.RU

WWW.2GIS.RU

IDE

WWW.2GIS.RUWWW.2GIS.RU

АНАЛОГИ

- AngularJS- Backbone.js- Ember.js- ExtJS- CorMVC- AsanaLuna- ...

WWW.2GIS.RUWWW.2GIS.RU

ВОПРОСЫ?

WWW.2GIS.RUWWW.2GIS.RU

top related