Slide 1

Slide 1 text

efactoring with Backbone.js R

Slide 2

Slide 2 text

JSDC 2012 Jace Ju 大澤木小鐵 http://plurk.com/jaceju http://twitter.com/jaceju http://www.jaceju.net

Slide 3

Slide 3 text

擦屁股達人 如何成為專業的

Slide 4

Slide 4 text

jQuery DOM 基礎 underscore.js 的使用方法 Backebone.js 原理 力有未逮之處

Slide 5

Slide 5 text

好好的沒事 跟人家學什麼重構 If it ain’t broke, don’t fix it.

Slide 6

Slide 6 text

那一年 我們學的 jQuery Write Once & runs everywhere.

Slide 7

Slide 7 text

那一年 我們學的 jQuery Write Once & runs everywhere. 萬屎 亂

Slide 8

Slide 8 text

身為工程師 都有摳別人屁股程式的時候 Programmers love copy

Slide 9

Slide 9 text

擦舊專案的屁股 Old project kills me

Slide 10

Slide 10 text

屎出不窮 Bug Happens

Slide 11

Slide 11 text

Time is all We need. 時間就像衛生紙

Slide 12

Slide 12 text

No Magic 沒有魔術

Slide 13

Slide 13 text

Keep the DOM structure stable. 儘可能不更動 DOM 結構

Slide 14

Slide 14 text

Same JavaScript Logic. JavaScript 邏輯 改動越少越好

Slide 15

Slide 15 text

Just do one thing at a time. 一次只做一件事

Slide 16

Slide 16 text

Step Ӊ᜷ by Step

Slide 17

Slide 17 text

0މ೻ό൯ࡈڭᎈ Version Control

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

0 Іਗʷ಻༊ Automated Testing

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

0 ࠠ࿴ృᐑ Cycle of refactoring

Slide 22

Slide 22 text

ࠠ࿴ృᐑ ੽வ༁ක֐ 重構 程式 測試 加入 版本 刪除 舊碼 測試

Slide 23

Slide 23 text

1ʱؓᔚϞ೻όᇁ Legacy code analysis

Slide 24

Slide 24 text

$(function () { $.get('json.php', function (json) { var dataList = json; var $input = $('#input').empty(); var $output = $('#output'); for(idx in dataList) { var dataItem = dataList[idx]; $input.append('
  • ' + dataItem.title + '
  • '); } $('a', $input).bind('click', function (e) { e.preventDefault(); var id = this.id.replace(/^item-/, ''); var dataItem = _.find(dataList, function(p) { return p.id == id; }); $('h1', $output).text(dataItem.title); $('p.desc', $output).text(dataItem.desc); }).eq(0).click(); }, 'json'); }); ੬ԈٙK2VFSZᄳج

    Slide 25

    Slide 25 text

    Data Input Init Output ̋ɝᕙЍਜ෯ᗆй $(function () { $.get('json.php', function (json) { var dataList = json; var $input = $('#input').empty(); var $output = $('#output'); for(idx in dataList) { var dataItem = dataList[idx]; $input.append('
  • ' + dataItem.title + '
  • '); } $('a', $input).bind('click', function (e) { e.preventDefault(); var id = this.id.replace(/^item-/, ''); var dataItem = _.find(dataList, function(p) { return p.id == id; }); $('h1', $output).text(dataItem.title); $('p.desc', $output).text(dataItem.desc); }).eq(0).click(); }, 'json'); });

    Slide 26

    Slide 26 text

    2 ˾౬༟ࣘᜊᅰ Replace Data Variables with Model/Collection

    Slide 27

    Slide 27 text

    [ { "id": 1, "title": "...", "desc": "..." }, { "id": 2, "title": "...", "desc": "..." }, { "id": 3, "title": "...", "desc": "..." }, { "id": 4, "title": "...", "desc": "..." }, { "id": 5, "title": "...", "desc": "..." } ] У؂ኜ၌הΫෂٙ+40/ࣸό

    Slide 28

    Slide 28 text

    [ { "id": 1, "title": "...", "desc": "..." }, { "id": 2, "title": "...", "desc": "..." }, { "id": 3, "title": "...", "desc": "..." }, { "id": 4, "title": "...", "desc": "..." }, { "id": 5, "title": "...", "desc": "..." } ] У؂ኜ၌הΫෂٙ+40/ࣸό 重要

    Slide 29

    Slide 29 text

    var Model = Backbone.Model.extend({ defaults: { title: '', desc: '' } }); var Collection = Backbone.Collection.extend({ model: Model }); ່֛.PEFM$PMMFDUJPOᗳй

    Slide 30

    Slide 30 text

    var Model = Backbone.Model.extend({ defaults: { title: '', desc: '' } }); var Collection = Backbone.Collection.extend({ model: Model }); ່֛.PEFM$PMMFDUJPOᗳй

    Slide 31

    Slide 31 text

    var dataList = json; for(idx in dataList) { var dataItem = dataList[idx]; // ... } var id = ...; var dataItem = _.find(dataList, function(d) { return d.id == id; }); $('h1').text(dataItem.title); $('p').text(dataItem.desc); ੬Ԉٙ༟ࣘஈଣᜌ፨

    Slide 32

    Slide 32 text

    var dataList = json; ͜$PMMFDUJPO̍ༀ+40/ᜊᅰ [ { "id": 1, "title": "...", "desc": "..." }, { "id": 2, "title": "...", "desc": "..." }, { "id": 3, "title": "...", "desc": "..." }, { "id": 4, "title": "...", "desc": "..." }, { "id": 5, "title": "...", "desc": "..." } ]

    Slide 33

    Slide 33 text

    var dataList = new Collection(json); ͜$PMMFDUJPO̍ༀ+40/ᜊᅰ Collection Model Model Model Model

    Slide 34

    Slide 34 text

    for(idx in dataList) { var dataItem = dataList[idx]; // ... } ͜$PMMFDUJPOGPS&BDI՟˾༟ࣘࠖ˾ [ { "id": 1, "title": "...", "desc": "..." }, { "id": 2, "title": "...", "desc": "..." }, { "id": 3, "title": "...", "desc": "..." }, { "id": 4, "title": "...", "desc": "..." }, { "id": 5, "title": "...", "desc": "..." } ]

    Slide 35

    Slide 35 text

    dataList.forEach(function (dataItem) { // ... }); ͜$PMMFDUJPOGPS&BDI՟˾༟ࣘࠖ˾ dataList : Collection dataItem : Model dataItem : Model dataItem : Model dataItem : Model

    Slide 36

    Slide 36 text

    [ { "id": 1, "title": "...", "desc": "..." }, { "id": 2, "title": "...", "desc": "..." }, { "id": 4, "title": "...", "desc": "..." }, { "id": 5, "title": "...", "desc": "..." } ] var id = ...; var dataItem = _.find(dataList, function(d) { return d.id == id; }); ҷ͜$PMMFDUJPOHFU ՟੻ఊഅ༟ࣘ { "id": 3, "title": "...", "desc": "..." }

    Slide 37

    Slide 37 text

    [ { "id": 1, "title": "...", "desc": "..." }, { "id": 2, "title": "...", "desc": "..." }, { "id": 4, "title": "...", "desc": "..." }, { "id": 5, "title": "...", "desc": "..." } ] var id = ...; var dataItem = _.find(dataList, function(d) { return d.id == id; }); ҷ͜$PMMFDUJPOHFU ՟੻ఊഅ༟ࣘ { "id": 3, "title": "...", "desc": "..." }

    Slide 38

    Slide 38 text

    var id = ...; var dataItem = dataList.get(id); ҷ͜$PMMFDUJPOHFU ՟੻ఊഅ༟ࣘ dataList : Collection dataItem : Model dataItem : Model dataItem : Model

    Slide 39

    Slide 39 text

    { "id": 3, "title": "...", "desc": "..." } $('h1').text(dataItem.title); $('p').text(dataItem.desc); ҷ͜.PEFMHFU ՟੻᙮׌࠽

    Slide 40

    Slide 40 text

    $('h1').text(dataItem.get('title')); $('p').text(dataItem.get('desc')); ҷ͜.PEFMHFU ՟੻᙮׌࠽ dataItem : Model get title desc

    Slide 41

    Slide 41 text

    3 ˏ͜ᅵو Introduce JavaScript Template

    Slide 42

    Slide 42 text

    var $dom = $('#view'); $dom.html('

    ' + dataItem.get('title') + '

    '); ੬Ԉٙ೥ࠦяତᜌ፨

    Slide 43

    Slide 43 text

    var $dom = $('#view'); $dom.html('

    ' + dataItem.get('title') + '

    '); ੬Ԉٙ೥ࠦяତᜌ፨ 這個叫 HTML

    Slide 44

    Slide 44 text

    var $dom = $('#view'); $dom.html('

    ' + dataItem.get('title') + '

    '); ່֛ᅵو

    Slide 45

    Slide 45 text

    var $dom = $('#view'); $dom.html('

    ' + dataItem.get('title') + '

    '); ່֛ᅵو

    Slide 46

    Slide 46 text

    var $dom = $('#view'); $dom.html('

    ' + dataItem.get('title') + '

    '); <h1>' + dataItem.get('title') + '</h1> ່֛ᅵو

    Slide 47

    Slide 47 text

    var $dom = $('#view'); $dom.html('

    ' + dataItem.get('title') + '

    '); <h1>' + dataItem.get('title') + '</h1> ່֛ᅵو

    Slide 48

    Slide 48 text

    var $dom = $('#view'); $dom.html('

    ' + dataItem.get('title') + '

    '); <h1><%= title %></h1> ່֛ᅵو

    Slide 49

    Slide 49 text

    var $dom = $('#view'); var template = _.template($('#view-template').html()); $dom.html('

    ' + dataItem.get('title') + '

    '); <h1><%= title %></h1> ່֛ᅵو˙ج

    Slide 50

    Slide 50 text

    var $dom = $('#view'); var template = _.template($('#view-template').html()); $dom.html('

    ' + dataItem.get('title') + '

    '); <h1><%= title %></h1> ͜ᅵو˙ج՟˾)5.-οЕ

    Slide 51

    Slide 51 text

    var $dom = $('#view'); var template = _.template($('#view-template').html()); $dom.html(template(dataItem.toJSON())); <h1><%= title %></h1> ͜ᅵو˙ج՟˾)5.-οЕ

    Slide 52

    Slide 52 text

    4ˏɝ7JFXᗳй Introduce View Class

    Slide 53

    Slide 53 text

    var $dom = $('#view'); var template = _.template($('#view-template').html()); $dom.html(template(dataItem.toJSON())); ່֛7JFXᗳй

    Slide 54

    Slide 54 text

    var $dom = $('#view'); var template = _.template($('#view-template').html()); $dom.html(template(dataItem.toJSON())); ່֛7JFXᗳй template

    Slide 55

    Slide 55 text

    var $dom = $('#view'); var template = _.template($('#view-template').html()); $dom.html(template(dataItem.toJSON())); ່֛7JFXᗳй template display

    Slide 56

    Slide 56 text

    var View = Backbone.View.extend({ render: function () { return this; } }); var $dom = $('#view'); var template = _.template($('#view-template').html()); $dom.html(template(dataItem.toJSON())); ່֛7JFXᗳй

    Slide 57

    Slide 57 text

    var View = Backbone.View.extend({ render: function () { return this; } }); var $dom = $('#view'); var template = _.template($('#view-template').html()); $dom.html(template(dataItem.toJSON())); ย୅ᅵو˙ج

    Slide 58

    Slide 58 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { return this; } }); var $dom = $('#view'); var template = _.template($('#view-template').html()); $dom.html(template(dataItem.toJSON())); ย୅ᅵو˙ج

    Slide 59

    Slide 59 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { return this; } }); var $dom = $('#view'); $dom.html(template(dataItem.toJSON())); ย୅ᅵو˙ج

    Slide 60

    Slide 60 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { return this; } }); var $dom = $('#view'); $dom.html(template(dataItem.toJSON())); ย୅ᜑͪᜌ፨

    Slide 61

    Slide 61 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { $dom.html(template(this.model.toJSON())); return this; } }); var $dom = $('#view'); $dom.html(template(dataItem.toJSON())); ย୅ᜑͪᜌ፨

    Slide 62

    Slide 62 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { $dom.html(this.template(this.model.toJSON())); return this; } }); var $dom = $('#view'); $dom.html(template(dataItem.toJSON())); ҷ͜7JFXٙᅵو˙ج

    Slide 63

    Slide 63 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; } }); var $dom = $('#view'); $dom.html(template(dataItem.toJSON())); ҷ͜7JFXٙFM᙮׌

    Slide 64

    Slide 64 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; } }); var $dom = $('#view'); $dom.html(template(dataItem.toJSON())); ୅ৰᔚٙяତᜌ፨

    Slide 65

    Slide 65 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; } }); var $dom = $('#view'); ୅ৰᔚٙяତᜌ፨

    Slide 66

    Slide 66 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; } }); var $dom = $('#view'); var view = new View({ }); ᜑͪ೥ࠦ

    Slide 67

    Slide 67 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; } }); var $dom = $('#view'); var view = new View({ el: '#view' }); ᜑͪ೥ࠦ

    Slide 68

    Slide 68 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; } }); var $dom = $('#view'); var view = new View({ el: '#view', model: dataItem }); ᜑͪ೥ࠦ

    Slide 69

    Slide 69 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; } }); var $dom = $('#view'); var view = new View({ el: '#view', model: dataItem }); ᜑͪ೥ࠦ

    Slide 70

    Slide 70 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; } }); var view = new View({ el: '#view', model: dataItem }); ᜑͪ೥ࠦ

    Slide 71

    Slide 71 text

    var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; } }); var view = new View({ el: '#view', model: dataItem }); view.render(); ᜑͪ೥ࠦ

    Slide 72

    Slide 72 text

    5ˏɝً࿒ي΁ Introduce Status Object

    Slide 73

    Slide 73 text

    Input Event Handler Output View ً࿒ي΁༶Ъࡡଣ

    Slide 74

    Slide 74 text

    Input Event Handler Output View ً࿒ي΁༶Ъࡡଣ

    Slide 75

    Slide 75 text

    Input Event Handler Output View Status ً࿒ي΁༶Ъࡡଣ

    Slide 76

    Slide 76 text

    var $input = $('#input'); var outputView = new OutputView({ el: '#output' }); $('a', $input).bind('click', function (e) { e.preventDefault(); var id = /* ... */; var dataItem = dataList.get(id); outputView.model = dataItem; outputView.render(); }); ̋ɝً࿒ي΁

    Slide 77

    Slide 77 text

    var status = new DataItem(); var $input = $('#input'); var outputView = new OutputView({ el: '#output' }); $('a', $input).bind('click', function (e) { e.preventDefault(); var id = /* ... */; var dataItem = dataList.get(id); outputView.model = dataItem; outputView.render(); }); ̋ɝً࿒ي΁

    Slide 78

    Slide 78 text

    var status = new DataItem(); var $input = $('#input'); var outputView = new OutputView({ el: '#output', model: status }); $('a', $input).bind('click', function (e) { e.preventDefault(); var id = /* ... */; var dataItem = dataList.get(id); outputView.model = dataItem; outputView.render(); }); ਗ਼ً࿒ي΁ഐΥՑ7JFXي΁ɪ

    Slide 79

    Slide 79 text

    var status = new DataItem(); var $input = $('#input'); var outputView = new OutputView({ el: '#output', model: status }); status.on('change', outputView.render, outputView); $('a', $input).bind('click', function (e) { e.preventDefault(); var id = /* ... */; var dataItem = dataList.get(id); outputView.model = dataItem; outputView.render(); }); ً່֛࿒ي΁ၾ7JFXي΁ٙʝਗ

    Slide 80

    Slide 80 text

    var status = new DataItem(); var $input = $('#input'); var outputView = new OutputView({ el: '#output', model: status }); status.on('change', outputView.render, outputView); $('a', $input).bind('click', function (e) { e.preventDefault(); var id = /* ... */; var dataItem = dataList.get(id); status.set(dataItem.toJSON()); outputView.model = dataItem; outputView.render(); }); ً͜࿒ي΁՟˾7JFXي΁ٙᜑͪᜌ፨

    Slide 81

    Slide 81 text

    var status = new DataItem(); var $input = $('#input'); var outputView = new OutputView({ el: '#output', model: status }); status.on('change', outputView.render, outputView); $('a', $input).bind('click', function (e) { e.preventDefault(); var id = /* ... */; var dataItem = dataList.get(id); status.set(dataItem.toJSON()); outputView.model = dataItem; outputView.render(); }); ً͜࿒ي΁՟˾7JFXي΁ٙᜑͪᜌ፨

    Slide 82

    Slide 82 text

    var status = new DataItem(); var $input = $('#input'); var outputView = new OutputView({ el: '#output', model: status }); status.on('change', outputView.render, outputView); $('a', $input).bind('click', function (e) { e.preventDefault(); var id = /* ... */; var dataItem = dataList.get(id); status.set(dataItem.toJSON()); }); ً͜࿒ي΁՟˾7JFXي΁ٙᜑͪᜌ፨

    Slide 83

    Slide 83 text

    6዆Υࠫࠦԫ΁ᜌ፨ Move DOM event handlers

    Slide 84

    Slide 84 text

    var InputView = Backbone.View.extend({ // ... }); var $input = $('#input'); $('a', $input).bind('click', function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); }); ย୅ԫ΁ஈଣዚՓ

    Slide 85

    Slide 85 text

    var InputView = Backbone.View.extend({ // ... }); var $input = $('#input'); $('a', $input).bind('click', function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); }); ย୅ԫ΁ஈଣዚՓ

    Slide 86

    Slide 86 text

    var InputView = Backbone.View.extend({ // ... events: { 'click a': 'changeOutput' }, changeOutput: function (e) { } }); var $input = $('#input'); $('a', $input).bind('click', function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); }); ย୅ԫ΁ஈଣዚՓ

    Slide 87

    Slide 87 text

    var InputView = Backbone.View.extend({ // ... events: { 'click a': 'changeOutput' }, changeOutput: function (e) { } }); var $input = $('#input'); $('a', $input).bind('click', function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); }); ย୅ԫ΁ஈଣዚՓ

    Slide 88

    Slide 88 text

    var InputView = Backbone.View.extend({ // ... events: { 'click a': 'changeOutput' }, changeOutput: function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); } }); var $input = $('#input'); $('a', $input).bind('click', function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); }); ย୅ԫ΁ஈଣዚՓ

    Slide 89

    Slide 89 text

    var InputView = Backbone.View.extend({ // ... events: { 'click a': 'changeOutput' }, changeOutput: function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); } }); var $input = $('#input'); $('a', $input).bind('click', function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); }); ย୅ԫ΁ஈଣዚՓ

    Slide 90

    Slide 90 text

    var InputView = Backbone.View.extend({ // ... events: { 'click a': 'changeOutput' }, changeOutput: function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); } }); ࡌ͍ਞϽᜊᅰ

    Slide 91

    Slide 91 text

    var InputView = Backbone.View.extend({ // ... events: { 'click a': 'changeOutput' }, changeOutput: function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); } }); var inputView = new InputView({ el: '#input' }); ࡌ͍ਞϽᜊᅰ

    Slide 92

    Slide 92 text

    var InputView = Backbone.View.extend({ // ... events: { 'click a': 'changeOutput' }, changeOutput: function (e) { var dataItem = dataList.get(id); status.set(dataItem.toJSON()); } }); var inputView = new InputView({ el: '#input', collection: dataList }); ࡌ͍ਞϽᜊᅰ

    Slide 93

    Slide 93 text

    var InputView = Backbone.View.extend({ // ... events: { 'click a': 'changeOutput' }, changeOutput: function (e) { var dataItem = this.collection.get(id); status.set(dataItem.toJSON()); } }); var inputView = new InputView({ el: '#input', collection: dataList }); ࡌ͍ਞϽᜊᅰ

    Slide 94

    Slide 94 text

    var InputView = Backbone.View.extend({ // ... events: { 'click a': 'changeOutput' }, changeOutput: function (e) { var dataItem = this.collection.get(id); status.set(dataItem.toJSON()); } }); var inputView = new InputView({ el: '#input', collection: dataList, model: status }); ࡌ͍ਞϽᜊᅰ

    Slide 95

    Slide 95 text

    var InputView = Backbone.View.extend({ // ... events: { 'click a': 'changeOutput' }, changeOutput: function (e) { var dataItem = this.collection.get(id); this.model.set(dataItem.toJSON()); } }); var inputView = new InputView({ el: '#input', collection: dataList, model: status }); ࡌ͍ਞϽᜊᅰ

    Slide 96

    Slide 96 text

    ̍ༀ"+"9 Replace $.ajax with Backbone.sync 7

    Slide 97

    Slide 97 text

    var DataList = Backbone.Collection.extend({ model: DataItem }); $(function () { $.get('json.php', function (json) { var dataList = new DataList(json); // ... status.on('change', outputView.render, outputView); inputView.render(); }, 'json'); }); ย୅4FSWFS၌"1*ٙխ̣Зໄ

    Slide 98

    Slide 98 text

    var DataList = Backbone.Collection.extend({ model: DataItem }); $(function () { $.get('json.php', function (json) { var dataList = new DataList(json); // ... status.on('change', outputView.render, outputView); inputView.render(); }, 'json'); }); ย୅4FSWFS၌"1*ٙխ̣Зໄ

    Slide 99

    Slide 99 text

    var DataList = Backbone.Collection.extend({ model: DataItem, url: 'json.php' }); $(function () { $.get('json.php', function (json) { var dataList = new DataList(json); // ... status.on('change', outputView.render, outputView); inputView.render(); }, 'json'); }); ย୅4FSWFS၌"1*ٙխ̣Зໄ

    Slide 100

    Slide 100 text

    var DataList = Backbone.Collection.extend({ model: DataItem, url: 'json.php' }); $(function () { var dataList = new DataList(json); // ... status.on('change', outputView.render, outputView); inputView.render(); }); ย୅4FSWFS၌"1*ٙխ̣Зໄ

    Slide 101

    Slide 101 text

    var DataList = Backbone.Collection.extend({ model: DataItem, url: 'json.php' }); $(function () { var dataList = new DataList(json); // ... status.on('change', outputView.render, outputView); inputView.render(); }); ୅ৰʔ̀ࠅٙᜊᅰ

    Slide 102

    Slide 102 text

    var DataList = Backbone.Collection.extend({ model: DataItem, url: 'json.php' }); $(function () { var dataList = new DataList(); // ... status.on('change', outputView.render, outputView); inputView.render(); }); ୅ৰʔ̀ࠅٙᜊᅰ

    Slide 103

    Slide 103 text

    var DataList = Backbone.Collection.extend({ model: DataItem, url: 'json.php' }); $(function () { var dataList = new DataList(); // ... status.on('change', outputView.render, outputView); inputView.render(); }); ່֛༟ࣘΝӉܝٙᙃ೯ԫ΁

    Slide 104

    Slide 104 text

    var DataList = Backbone.Collection.extend({ model: DataItem, url: 'json.php' }); $(function () { var dataList = new DataList(); // ... status.on('change', outputView.render, outputView); inputView.render(); dataList.on('all', inputView.render, inputView); }); ່֛༟ࣘΝӉܝٙᙃ೯ԫ΁

    Slide 105

    Slide 105 text

    var DataList = Backbone.Collection.extend({ model: DataItem, url: 'json.php' }); $(function () { var dataList = new DataList(); // ... status.on('change', outputView.render, outputView); dataList.on('all', inputView.render, inputView); }); ່֛༟ࣘΝӉܝٙᙃ೯ԫ΁

    Slide 106

    Slide 106 text

    var DataList = Backbone.Collection.extend({ model: DataItem, url: 'json.php' }); $(function () { var dataList = new DataList(); // ... status.on('change', outputView.render, outputView); dataList.on('all', inputView.render, inputView); dataList.fetch(); }); ່֛༟ࣘΝӉܝٙᙃ೯ԫ΁

    Slide 107

    Slide 107 text

    var DataItem = Backbone.Model.extend({ ... }); var DataList = Backbone.Collection.extend({ ... }); var InputView = Backbone.View.extend({ ... }); var OutputView = Backbone.View.extend({ ... }); $(function () { var dataList = new DataList(); var status = new DataItem(); var inputView = new InputView({ el: '#input', collection: dataList, model: status }); var outputView = new OutputView({ el: '#output', model: status }); status.on('change', outputView.render, outputView); dataList.on('all', inputView.render, inputView); dataList.fetch(); }); 最後的成果

    Slide 108

    Slide 108 text

    這就是 重構!

    Slide 109

    Slide 109 text

    在 GitHub 上 叉 我 https://github.com/jaceju/refactoring_with_backbone.js

    Slide 110

    Slide 110 text

    總結 Conclusion

    Slide 111

    Slide 111 text

    小步前進 Refactoring for next step.

    Slide 112

    Slide 112 text

    精益求精 Refactoring always.

    Slide 113

    Slide 113 text

    職責與解耦 SRP & Decoupling.

    Slide 114

    Slide 114 text

    克服惰性 Do it right now!

    Slide 115

    Slide 115 text

    謝謝大家 Thank you. 投影片網址: http://goo.gl/ivDuz