From 4ca2f51d5e58236f928652a82ef3d94ac84bcb80 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 27 May 2016 17:08:04 -0700 Subject: [PATCH] [API] Use subclass style --- src/api/View.js | 26 ++------ tutorials/todo/todo.js | 142 +++++++++++++++++++++-------------------- 2 files changed, 79 insertions(+), 89 deletions(-) diff --git a/src/api/View.js b/src/api/View.js index 2bdd01c763..1fcdf30f85 100644 --- a/src/api/View.js +++ b/src/api/View.js @@ -1,35 +1,19 @@ define(['EventEmitter'], function (EventEmitter) { - function View(definition) { - var self = this; - var state = definition.state ? definition.state() : {}; - - function render() { - if (definition.render) { - definition.render(self.elements(), self.model(), state); - } - } - + function View() { EventEmitter.call(this); - this.state = { elements: [], model: undefined }; - - if (definition.elements) { - this.elements(definition.elements()); - } - if (definition.initialize) { - definition.initialize(this.elements(), state, render); - } - this.on('model', render); } View.prototype = Object.create(EventEmitter.prototype); ['elements', 'model'].forEach(function (method) { View.prototype[method] = function (value) { + this.viewState = + this.viewState || { elements: [], model: undefined }; if (arguments.length > 0) { - this.state[method] = value; + this.viewState[method] = value; this.emit(method, value); } - return this.state[method]; + return this.viewState[method]; } }); diff --git a/tutorials/todo/todo.js b/tutorials/todo/todo.js index de69086d99..4c52744dac 100644 --- a/tutorials/todo/todo.js +++ b/tutorials/todo/todo.js @@ -21,78 +21,84 @@ define([ creatable: true }); - todoType.view(mct.regions.main, function (domainObject) { - var view = new mct.View({ - state: function () { - return { - filter: "all" - }; + function TodoView(domainObject) { + mct.View.apply(this); + this.filterValue = "all"; + this.elements($(todoTemplate)); + + var $els = $(this.elements()); + this.$buttons = { + all: $els.find('.example-todo-button-all'), + incomplete: $els.find('.example-todo-button-incomplete'), + complete: $els.find('.example-todo-button-complete') + }; + + this.initialize(); + this.on('model', this.render.bind(this)); + this.model(domainObject); + } + + TodoView.prototype = Object.create(mct.View.prototype); + + TodoView.prototype.setFilter = function (value) { + this.filterValue = value; + this.render(); + }; + + TodoView.prototype.initialize = function () { + Object.keys(this.$buttons).forEach(function (k) { + this.$buttons[k].on('click', this.setFilter.bind(this, k)); + }, this); + }; + + TodoView.prototype.render = function () { + var $els = $(this.elements()); + var domainObject = this.model(); + var tasks = domainObject.getModel().tasks; + var $message = $els.find('.example-message'); + var $list = $els.find('.example-todo-task-list'); + var $buttons = this.$buttons; + var filters = { + all: function () { + return true; }, - elements: $.bind(null, todoTemplate), - initialize: function (elements, state, render) { - var $els = $(elements); - var $buttons = { - all: $els.find('.example-todo-button-all'), - incomplete: $els.find('.example-todo-button-incomplete'), - complete: $els.find('.example-todo-button-complete') - }; - Object.keys($buttons).forEach(function (k) { - $buttons[k].on('click', function () { - state.filter = k; - render(); - }); - }); + incomplete: function (task) { + return !task.completed; }, - render: function (elements, domainObject, state) { - var $els = $(elements); - var tasks = domainObject.getModel().tasks; - var $message = $els.find('.example-message'); - var $list = $els.find('.example-todo-task-list'); - var $buttons = { - all: $els.find('.example-todo-button-all'), - incomplete: $els.find('.example-todo-button-incomplete'), - complete: $els.find('.example-todo-button-complete') - }; - var filters = { - all: function () { - return true; - }, - incomplete: function (task) { - return !task.completed; - }, - complete: function (task) { - return task.completed; - } - }; - - Object.keys($buttons).forEach(function (k) { - $buttons[k].toggleClass('selected', state.filter === k); - }); - tasks = tasks.filter(filters[state.filter]); - - $list.empty(); - tasks.forEach(function (task, index) { - var $taskEls = $(taskTemplate); - var $checkbox = $taskEls.find('.example-task-checked'); - $checkbox.prop('checked', task.completed); - $taskEls.find('.example-task-description') - .text(task.description); - - $checkbox.on('change', function () { - var checked = !!$checkbox.prop('checked'); - mct.verbs.mutate(domainObject, function (model) { - model.tasks[index].completed = checked; - }); - }); - - $list.append($taskEls); - }); - - $message.toggle(tasks.length < 1); + complete: function (task) { + return task.completed; } + }; + var filterValue = this.filterValue; + + Object.keys($buttons).forEach(function (k) { + $buttons[k].toggleClass('selected', filterValue === k); }); - view.model(domainObject); - return view; + tasks = tasks.filter(filters[filterValue]); + + $list.empty(); + tasks.forEach(function (task, index) { + var $taskEls = $(taskTemplate); + var $checkbox = $taskEls.find('.example-task-checked'); + $checkbox.prop('checked', task.completed); + $taskEls.find('.example-task-description') + .text(task.description); + + $checkbox.on('change', function () { + var checked = !!$checkbox.prop('checked'); + mct.verbs.mutate(domainObject, function (model) { + model.tasks[index].completed = checked; + }); + }); + + $list.append($taskEls); + }); + + $message.toggle(tasks.length < 1); + }; + + todoType.view(mct.regions.main, function (domainObject) { + return new TodoView(domainObject); }); mct.type('example.todo', todoType);