Understanding the MVC,MVP,MVVM in JavaScript

Understanding the MVC,MVP,MVVM in JavaScript

JSDC 2013 Slides

F830ec52d5bf72ee64fd1a43a6a82a49?s=128

大澤木小鐵

May 19, 2013
Tweet

Transcript

  1. 2.
  2. 22.

    MV*

  3. 31.

    var myapp = {}; myapp.Model = function () { var

    val = 0; this.add = function (v) { if (val < 100) val += v; }; this.sub = function (v) { if (val > 0) val -= v; }; this.getVal = function () { return val; }; }; Model 資料的狀態
  4. 32.

    var myapp = {}; myapp.Model = function () { var

    val = 0; this.add = function (v) { if (val < 100) val += v; }; this.sub = function (v) { if (val > 0) val -= v; }; this.getVal = function () { return val; }; }; Model 操作內部狀態的⾏行為
  5. 33.

    myapp.View = function () { var $num = $('#num'); var

    $incBtn = $('#increase'); var $decBtn = $('#decrease'); this.render = function (model) { $num.text(model.getVal() + 'px'); }; }; View 管理視覺元件
  6. 34.

    View myapp.View = function () { var $num = $('#num');

    var $incBtn = $('#increase'); var $decBtn = $('#decrease'); this.render = function (model) { $num.text(model.getVal() + 'px'); }; }; 呈現資料
  7. 35.

    MVC

  8. 46.

    myapp.Model = function () { // ... var views =

    []; this.register = function (view) { views.push(view); } var self = this; this.notify = function () { for (var i = 0; i < views.length; i++) { views[i].render(self); } }; }; Model Model 擁有 View 的參考
  9. 47.

    myapp.Model = function () { // ... var views =

    []; this.register = function (view) { views.push(view); } var self = this; this.notify = function () { for (var i = 0; i < views.length; i++) { views[i].render(self); } }; }; Model Model 有變化時通知 View 更新
  10. 50.

    myapp.Controller = function () { var model = null; var

    view = null; this.init = function () { model = new myapp.Model(); view = new myapp.View(this); model.register(view); model.notify(); }; }; Controller Controller 初始化 Model 與 View
  11. 51.

    myapp.Controller = function () { var model = null; var

    view = null; this.init = function () { model = new myapp.Model(); view = new myapp.View(this); model.register(view); model.notify(); }; }; Controller View 向 Model 註冊⾃自⼰己
  12. 52.

    myapp.Controller = function () { // ... this.increase = function

    () { model.add(1); model.notify(); }; this.decrease = function () { model.sub(1); model.notify(); }; }; Controller Controller 負責控制 Model
  13. 68.

    myapp.Model = function () { var val = 0; this.add

    = function (v) { if (val < 100) val += v; }; this.sub = function (v) { if (val > 0) val -= v; }; this.getVal = function () { return val; }; }; Model 不需要觀察者模式
  14. 69.

    myapp.Presenter = function (view) { var _model = new myapp.Model();

    var _view = view; _view.render(_model.getVal()); this.increase = function () { _model.add(1); _view.render(_model.getVal()); }; this.decrease = function () { _model.sub(1); _view.render(_model.getVal()); }; }; Presenter Presenter 將 Model 內容 傳遞給 View
  15. 70.

    myapp.View = function () { // ... this.init = function

    () { var presenter = new myapp.Presenter(this); $incBtn.click(presenter.increase); $decBtn.click(presenter.decrease); }; } View View 將請求委派給 Presenter
  16. 74.
  17. 80.

    myapp.ViewModel = function () { var model = new myapp.Model();

    this.num = ko.observable(model.getVal()); this.val = ko.computed(function() { return this.num() + 'px'; }, this); }; ViewModel View 利⽤用觀察者模式 將 ViewModel 結合起來
  18. 81.

    myapp.ViewModel = function () { // ... this.increase = function

    () { model.add(1); this.num(model.getVal()); }; this.decrease = function () { model.sub(1); this.num(model.getVal()); }; }; ko.applyBindings(new myapp.ViewModel()); ViewModel ViewModel 操作 Model 並將資料 binding 到 View 元素上
  19. 82.

    myapp.ViewModel = function () { // ... this.increase = function

    () { model.add(1); this.num(model.getVal()); }; this.decrease = function () { model.sub(1); this.num(model.getVal()); }; }; ko.applyBindings(new myapp.ViewModel()); ViewModel 透過 Framework 結合 View 與 ViewModel
  20. 84.
  21. 90.

    var Event = { _events: {}, on: function(name, callback, context)

    { ! this._events || (this._events = {}); ! var events = this._events[name] ! ! ! || (this._events[name] = []); ! events.push({ ! ! callback: callback, ! ! ctx: context ! }); } }; Event.on 將 callback 及 context 加到事件的庫裡
  22. 91.

    Event.trigger var Event = { // ... trigger: function(name) {

    ! var events = this._events[name]; ! for (var i = 0; i < events.length; i++) { ! ! (ev = events[i]).callback.call(ev.ctx); ! } } }; 將事件對應的 callback ⼀一⼀一找出來執⾏行
  23. 92.

    Event.on('event1', function () { ! alert('callback 1'); }, this); Event.on('event1',

    function () { ! alert('callback 2'); }, this); Event.on('event2', function () { ! alert('callback 3'); }, this); Event.trigger('event1'); Event.trigger('event2'); Event Demo 事件綁定 callback
  24. 93.

    Event.on('event1', function () { ! alert('callback 1'); }, this); Event.on('event1',

    function () { ! alert('callback 2'); }, this); Event.on('event2', function () { ! alert('callback 3'); }, this); Event.trigger('event1'); Event.trigger('event2'); Event Demo 觸發事件
  25. 98.