Эти страшные буквы MV*

Эти страшные буквы MV*

Александра Шинкевич (@neesoglasnaja)

Flux

bit.ly/wsd-mv

Пример

TodoList


Никакой архитектуры

1. HTML

Никакой архитектуры

1. HTML

2. JS

Никакой архитектуры

1. HTML

2. JS

3. AJAX

Проблемы

Преимущества MV*

MVC

MVC

MVC

MVC

MVC

MVC

MVC

MVC

MVC

MVC

MVC

MVC

Пример MVC

MVC: HTML

<!-- ... -->    <body>       <script src="js/utils.js"></script>       <script src="js/models.js"></script>       <script src="js/views.js"></script>       <script src="js/controllers.js"></script>       <script src="js/app.js"></script>    </body></html>

MVC: HTML

<!-- ... -->    <body>       <script src="js/utils.js"></script>       <script src="js/models.js"></script>       <script src="js/views.js"></script>       <script src="js/controllers.js"></script>       <script src="js/app.js"></script>    </body></html>

MVC: app.js

var list = new ListController();

MVC: HTML

<!-- ... -->    <body>       <script src="js/utils.js"></script>       <script src="js/models.js"></script>       <script src="js/views.js"></script>       <script src="js/controllers.js"></script>       <script src="js/app.js"></script>    </body></html>

MVC: controllers.js

function ListController() {    var model = new TasksModel();    var view = new ListView(model);    view.addCreateTaskHandler(function(taskTitle) { ... });    view.addCheckedHandler(function(id) { ... });}

MVC: controllers.js

function ListController() {    var model = new TasksModel();    var view = new ListView(model);    view.addCreateTaskHandler(function(taskTitle) { ... });    view.addCheckedHandler(function(id) { ... });}

MVC: HTML

<!-- ... -->    <body>       <script src="js/utils.js"></script>       <script src="js/models.js"></script>       <script src="js/views.js"></script>       <script src="js/controllers.js"></script>       <script src="js/app.js"></script>    </body></html>

MVC: views.js

function ListView(model) {    var html = $( ... );    customEvents.registerEvent('UpdateList');    customEvents.addEventListener('UpdateList', function() { ... });    return {        addCreateTaskHandler: function(handler) { ... },        addCheckedHandler: function(handler) { ... }    };}

MVC: views.js

function ListView(model) {    var html = $( ... );    customEvents.registerEvent('UpdateList');    customEvents.addEventListener('UpdateList', function() { ... });    return {        addCreateTaskHandler: function(handler) { ... },        addCheckedHandler: function(handler) { ... }    };}

MVC: views.js

function ListView(model) {    var html = $( ... );    customEvents.registerEvent('UpdateList');    customEvents.addEventListener('UpdateList', function() { ... });    return {        addCreateTaskHandler: function(handler) { ... },        addCheckedHandler: function(handler) { ... }    };}

MVC: HTML

 <!-- ... -->    <body>       <script src="js/utils.js"></script>       <script src="js/models.js"></script>       <script src="js/views.js"></script>       <script src="js/controllers.js"></script>       <script src="js/app.js"></script>    </body></html>

MVC: models.js

function TasksModel() {    return {        data: {},        getAll: function() { ... },        addItem: function(name) { ... },        deleteItem: function(id) { ... },    };};

MVC: models.js

addItem: function(name) {    this.data[(new Date()).getTime()] = name;    customEvents.dispatchEvent('UpdateList');}

MVC: Приложение

MVP

MVP

MVP

MVP

MVP

MVP

MVP

MVP

MVP

MVP

Пример MVP

MVP: HTML

 <!-- ... -->   <body>      <script src="js/utils.js"></script>      <script src="js/models.js"></script>       <script src="js/views.js"></script>       <script src="js/presenters.js"></script>      <script src="js/app.js"></script>    </body></html>

MVP: HTML

 <!-- ... -->   <body>      <script src="js/utils.js"></script>      <script src="js/models.js"></script>       <script src="js/views.js"></script>       <script src="js/presenters.js"></script>      <script src="js/app.js"></script>    </body></html>

MVP: app.js

var list = new ListPresenter();

MVP: HTML

 <!-- ... -->   <body>      <script src="js/utils.js"></script>      <script src="js/models.js"></script>       <script src="js/views.js"></script>       <script src="js/presenters.js"></script>      <script src="js/app.js"></script>    </body></html>

MVP: presenters.js

function ListPresenter() {    var model = new TasksModel();    var view = new ListView(model.getAll());    view.addCreateTaskHandler(function(taskTitle) { ... });    view.addCheckedHandler(function(id) { ... });    customEvents.registerEvent('UpdateList');    customEvents.addEventListener('UpdateList', function() { ... });}

MVP: HTML

 <!-- ... -->   <body>      <script src="js/utils.js"></script>      <script src="js/models.js"></script>       <script src="js/views.js"></script>       <script src="js/presenters.js"></script>      <script src="js/app.js"></script>    </body></html>

MVP: views.js

function ListView(data) {    var html = $( ... );    return {        addCreateTaskHandler: function(handler) { ... },        addCheckedHandler: function(handler) { ... },        updateView: function(data) { ... }    };}

MVP: Приложение

MVVM

Связывание данных

Это такой механизм, при котором изменение значения модели с любой стороны (View или Model) моментально вступает в силу на другой.

MVVM

Пример MVVM

Knockout.js

Open-source фреймворк, реализующий Model-View-ViewModel на Javascript и data binding.

MVVM: HTML

    <body>       <!-- Разметка html -->       <script src="js/knockout-3.4.0.min.js"></script>       <script src="js/viewmodel.js"></script>    </body></html>

MVVM: HTML

<form data-bind="submit: addItem">    <ul data-bind="foreach: items">        <li>            <label data-bind="click: $parent.removeItem">                <input type="checkbox">                <span data-bind="text: $data"></span>            </label>        </li><!--      ...      -->

MVVM: HTML

    <body>       <!-- Разметка html -->       <script src="js/knockout-3.4.0.min.js"></script>       <script src="js/viewmodel.js"></script>    </body></html>

MVVM: viewmodel.js

var ListViewModel = function(items) {    return {       items: ko.observableArray(items),       itemToAdd: ko.observable(""),        addItem: function() { ... },        removeItem: function() { ... },    };};ko.applyBindings(new ListViewModel([]));

MVVM: viewmodel.js

var ListViewModel = function(items) {    return {       items: ko.observableArray(items),       itemToAdd: ko.observable(""),        addItem: function() { ... },        removeItem: function() { ... },    };};ko.applyBindings(new ListViewModel([]));

MVVM: viewmodel.js

var ListViewModel = function(items) {    return {       items: ko.observableArray(items),       itemToAdd: ko.observable(""),        addItem: function() { ... },        removeItem: function() { ... },    };};ko.applyBindings(new ListViewModel([]));

MVVM: Приложение

Что выбрать

Хочу больше

Вместо вывода

Вопросы?