Knockoutjs на примере 2ГИС-Онлайн

Preview:

DESCRIPTION

 

Citation preview

ИЛЬЯ ТАРАТУХИН

KNOCKOUT.js НА ПРИМЕРЕ

2ГИС-ОНЛАЙН

ДОКЛАДЧИК

Разрабатывал АСУ ТП

для горно-шахтного

оборудования

Спикер CodeFest

2012

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

>5 млн API карт

>8 млн Карты 2ГИС

>3 млн

С 2011 года работаю в 2ГИС

WWW.2GIS.RU

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 = 'Привет, мир!';

$('#container').appendChild(newDiv);

Привет, мир!

WWW.2GIS.RU

WHERE IS

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

jQueryTemplate

Mustache

Underscore.js

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

Pure

WWW.2GIS.RU WWW.2GIS.RU

СОБЫТИЯ

.firmShort

.firmFull #firmList

WWW.2GIS.RU WWW.2GIS.RU

СОБЫТИЯ

$("#firmTemplate").tmpl(someData)

.appendTo("#firmList");

$('.firmShort').live({

click: function() {

showFirmCard(this);

}

});

$('.firmFull').live({

click: function() {

hideFirmCard(this);

}

});

WWW.2GIS.RU WWW.2GIS.RU

СОБЫТИЯ

WWW.2GIS.RU WWW.2GIS.RU

KNOCKOUT

WWW.2GIS.RU WWW.2GIS.RU

ПОЧЕМУ KNOCKOUT?

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

WWW.2GIS.RU WWW.2GIS.RU

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

ПОЧЕМУ KNOCKOUT?

Удобное разделение

логики и шаблонов

WWW.2GIS.RU WWW.2GIS.RU

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

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

ПОЧЕМУ KNOCKOUT?

Функционален, есть

декларативные биндинги

WWW.2GIS.RU WWW.2GIS.RU

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

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

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

биндинги

ПОЧЕМУ KNOCKOUT?

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

WWW.2GIS.RU WWW.2GIS.RU

MVVM

View Model

ViewModel

UI Logic Business Logic

Application Logic

WWW.2GIS.RU WWW.2GIS.RU

KNOCKOUT

WWW.2GIS.RU WWW.2GIS.RU

<div class="dg-search-result-header">

<span data-bind="text:

what_text"></span>,

<span data-bind="text:

where_text"></span></div>

KNOCKOUT

WWW.2GIS.RU WWW.2GIS.RU

function vm() {

this.what_text = ko.observable('');

}

ko.applyBindings(new vm());

...

vm.what_text(response.what);

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

KO.OBSERVABLE

WWW.2GIS.RU WWW.2GIS.RU

МАССИВЫ

WWW.2GIS.RU WWW.2GIS.RU

response.result = [

{

firmName = 'Завод №1',

...

},

{

firmName = 'Завод №2';

...

}]

МАССИВЫ

WWW.2GIS.RU WWW.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.RU WWW.2GIS.RU

BINDINGS

WWW.2GIS.RU WWW.2GIS.RU

<div class="dg-search-result-header">

<span data-bind="text:

what_text"></span>,

<span data-bind="text:

where_text"></span></div>

BINDINGS

WWW.2GIS.RU WWW.2GIS.RU

BINDINGS

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

- Control flow

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

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

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

WWW.2GIS.RU WWW.2GIS.RU

.firmShort

.firmFull

BINDINGS

WWW.2GIS.RU WWW.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.RU WWW.2GIS.RU

BINDINGS

WWW.2GIS.RU WWW.2GIS.RU

data-bind="visible: isVisible,

click: toggleVisibility"

BINDINGS

WWW.2GIS.RU WWW.2GIS.RU

data-bind="visible: isVisible,

click: toggleVisibility"

toggleVisibility = function() {

this.isVisible(!this.isVisible());}

BINDINGS

WWW.2GIS.RU WWW.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.RU WWW.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.RU WWW.2GIS.RU

data-bind="animateVisible: isVisible,

click: toggleVisibility"

toggleVisibility = function() {

this.isVisible(!this.isVisible());}

BINDINGS

WWW.2GIS.RU WWW.2GIS.RU

<script type="text/my-tpl" id="firm-tpl">

//firm template code</script>

BINDINGS

WWW.2GIS.RU WWW.2GIS.RU

<script type="text/my-tpl" id="catalog-tpl">

//some template code

<div data-bind="template: {

name: 'firm-tpl',

foreach: firms

}"></div>

</script>

BINDINGS

WWW.2GIS.RU WWW.2GIS.RU

BINDINGS

BINDING-CONTEXT

vm

vm.firms[n]

WWW.2GIS.RU WWW.2GIS.RU

ПЕЧАТЬ

WWW.2GIS.RU WWW.2GIS.RU

<script type="text/my-tpl" id="print-tpl">

//some template code

<div data-bind="template: {

name: 'firm-tpl',

foreach: firms,

templateOptions: {

isPrint: 1

}

}"></div>

</script>

ПЕЧАТЬ

WWW.2GIS.RU WWW.2GIS.RU

BINDINGS

<div class="phone-number"

data-bind="visible:

$context.isPrint)">

<!-- Some code-->

</div>

WWW.2GIS.RU WWW.2GIS.RU

BINDINGS

<div class="contacts"

data-bind="template: {

name: 'firm-tpl',

data: $data,

templateOptions: {

isPrint: $context.isPrint

}

}">

<!-- Some code-->

</div>

WWW.2GIS.RU WWW.2GIS.RU

$context

$data

templateOptions

BINDING CONTEXT

WWW.2GIS.RU WWW.2GIS.RU

BINDING CONTEXT

$context

$data

templateOptions

• $parent

• $parentContext

• $root

• $index

• $element

WWW.2GIS.RU WWW.2GIS.RU

function initBalloon (options) {

map.createBalloon({

point: options.point;

content: options.template

}); }

BINDINGS

WWW.2GIS.RU WWW.2GIS.RU

function initBalloon (options) {

map.createBalloon({

point: options.point;

content: options.template

});

var container = $('#balloonContent');

ko.applyBindingsToNode(container ,

vm);}

BINDINGS

WWW.2GIS.RU WWW.2GIS.RU

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

WWW.2GIS.RU WWW.2GIS.RU

this.showPreloader = ko.computed(function(){

return this.firmsLoad() &&

this.geoLoad();});

<span id="preloader"

data-bind="visible: showPreloader">

</span>

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

WWW.2GIS.RU WWW.2GIS.RU

Не наблюдайте один computed

внутри другого

KO.COMPUTED

WWW.2GIS.RU WWW.2GIS.RU

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

KO.COMPUTED

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

computed

WWW.2GIS.RU WWW.2GIS.RU

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

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

KO.COMPUTED

Используйте computed только там,

где это необходимо

WWW.2GIS.RU WWW.2GIS.RU

PLUGINS

WWW.2GIS.RU WWW.2GIS.RU

PLUGINS

knockout.address

WWW.2GIS.RU WWW.2GIS.RU

PLUGINS

knockout.address

window.location vm.myObservable

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

WWW.2GIS.RU WWW.2GIS.RU

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

PLUGINS

WWW.2GIS.RU WWW.2GIS.RU

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

107 22 18

Observable

Computed Observable

Array

WWW.2GIS.RU WWW.2GIS.RU

Functions

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

200+ 107 22 18

WWW.2GIS.RU WWW.2GIS.RU

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

200+ 107

22

18

13

WWW.2GIS.RU WWW.2GIS.RU

Namespace.ViewModelModules.<ourModule> = {

_observables: {

<ourObservable>: <defaultData>,

<ourComputed>:

function(){/*computedCode*/}

},

<someProperty>: 100500,

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

<function>: function(){/*fBody*/}}

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

WWW.2GIS.RU WWW.2GIS.RU

Namespace.ViewModelModules.<ourModule> = {

_observables: {

<ourObservable>: <defaultData>,

<ourComputed>:

function(){/*computedCode*/}

},

<someProperty>: 100500,

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

<function>: function(){/*fBody*/}}

WWW.2GIS.RU

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

150

WWW.2GIS.RU WWW.2GIS.RU

IDE

data-bind="

//очень много

//кода

//который выглядит

//как одна сплошная строка

"

WWW.2GIS.RU WWW.2GIS.RU

IDE

WWW.2GIS.RU WWW.2GIS.RU

WWW.2GIS.RU

IDE

WWW.2GIS.RU WWW.2GIS.RU

АНАЛОГИ

- AngularJS

- Backbone.js

- Ember.js

- ExtJS

- CorMVC

- AsanaLuna

- ...

WWW.2GIS.RU WWW.2GIS.RU

ВОПРОСЫ?

WWW.2GIS.RU WWW.2GIS.RU

Recommended