$30 off During Our Annual Pro Sale. View Details »

Marionette.js in Single Page Application

koba04
January 21, 2014

Marionette.js in Single Page Application

Marionette.jsのView周りについてを中心にSingle Page Applicationを作るときの話

koba04

January 21, 2014
Tweet

More Decks by koba04

Other Decks in Programming

Transcript

  1. Marionette.js in Single Page Application
    @koba04 (2014/1/21)

    View Slide

  2. Agenda
    • Single Page Applicationʹ͓͍ͯMarionette.jsΛ࢖͏ཧ༝

    • Marionette.jsͷViewपΓͷߏ଄ʹ͍ͭͯ

    • Marionette.jsͷศརͳػೳͨͪ

    View Slide

  3. What is Single Page Application? (SPA)
    • http://en.wikipedia.org/wiki/Single-page_application

    !
    !
    • αʔόʔ͸JSON API͚ͩΛఏڙ͍ͯͯ͠ϖʔδભҠ(࠶ಡΈࠐΈ)͸ൃੜͤͣɺ
    JavaScriptͰroutingͷ؅ཧ΍templateͳͲΛ༻͍ͨը໘ͷߋ৽ͳͲΛશͯߦ͏

    • http://www.manning.com/mikowski/
    In an SPA, either all necessary code – HTML, JavaScript, and CSS – is retrieved with a single page load,[1]
    or the appropriate resources are dynamically loaded and added to the page as necessary, usually in
    response to user actions. The page does not reload at any point in the process, nor does control transfer
    to another page, although modern web technologies (such as those included in HTML5) can provide the
    perception and navigability of separate logical pages in the application. Interaction with the single page
    application often involves dynamic communication with the web server behind the scenes.

    View Slide

  4. Backbone (1.1.0)
    • http://backbonejs.org/

    • ΞϓϦέʔγϣϯΛModel, Collection, ViewͳͲͷཁૉͰߏ଄Խͯ͘͠ΕΔϑ
    ϨʔϜϫʔΫ

    • Backbone.EventsʹΑΔObserverύλʔϯͰͷ΍ΓͱΓ

    • ࠷௿ݶͷػೳ͚͕ͩఏڙ͞Ε͍ͯΔͷͰ͜Ε͚ͩͰSPAΛͭ͘Ζ͏ͱ͢Δͱɺ
    ͦͷ্ʹ΋͏Ұ૚ϑϨʔϜϫʔΫΛߏஙͤ͟ΔΛಘͳ͍

    • ϝϞϦϦʔΫɺZombieViewා͍…

    • SPAͷ৔߹ɺϝϞϦϦʔΫ͸க໋త

    View Slide

  5. Marionette (1.5.1)
    • http://marionettejs.com/

    • Backbone.jsΛϕʔεʹViewपΓΛத৺ʹڧԽͨ͠ϑϨʔϜϫʔΫ

    • BackboneܥͷϥΠϒϥϦͷதͰ࠷΋Star͞Ε͍ͯΔ

    • Backbone.jsΛϕʔεʹ࣮ͨ͠૷ʹͳ͍ͬͯΔͷͰιʔε͕ಡΈ΍͍͢͠ɺυ
    Ωϡϝϯτ΋Θ͔Γ΍͍͢

    • https://leanpub.com/marionette-gentle-introduction

    View Slide

  6. http://backplug.io

    View Slide

  7. Backbone Is Not Enough
    • http://blog.shinetech.com/2013/09/06/backbone-is-not-enough/
    When you pick a library like Backbone for a large SPA, sticky questions quickly arise. For
    example:

    ▪ How do I structure nested views and controllers? This is usually the first question I get
    asked by beginners. And I can honestly say after all this time: I don’t know – I’d have to do it
    myself for your particular use-case and then get back to you.

    ▪ How do I test my views? Backbone hasn’t got testing baked into it, so you have to piece
    together testing yourself. For views, this is hard – so hard that many people don’t bother to
    do it.

    ▪ Why is my app leaking memory? In SPAs, objects can hang around for a long time, rather
    than being recreated on a page refresh. This can be really useful, but also means that you
    have to make sure those objects that are not actually being used don’t take up memory.

    ▪ Why is my rendering so slow? With Backbone, it’s really easy to make many small updates
    to the DOM for a single user interaction. For large data sets, this lead to a poor user
    experience.

    View Slide

  8. Backbone Antipattern
    • http://blog.shinetech.com/2013/11/26/backbone-antipatterns/

    • BackboneͰ։ൃ͢Δͱ͖ʹ΍Γ͕ͪͳΞϯνύλʔϯ͕10ݸ঺հ͞Ε͍ͯΔ
    Antipattern #1: Building a single page app when you don’t need to
    Antipattern #2: Using Backbone When You Should Use Another Framework

    Antipattern #3: No View Tests

    Antipattern #4: No Memory Management

    Antipattern #5: Data Attributes in the DOM

    Antipattern #6: Rendering Templates Asynchronously

    Antipattern #7: Undocumented Options

    Antipattern #8: Premature Use of Custom Events

    Antipattern #9: Building a Relationship Mapper

    Antipattern #10: Redundant Divs

    View Slide

  9. Using Backbone When You Should Use Another Framework
    • ήʔϜͷΑ͏ͳDOMΛΨπΨπ৮ΔΑ͏ͳΞϓϦͰͳ͘ɺJSON APIΛୟ͍ͯ
    ͦͷ݁ՌΛදࣔ͢ΔΑ͏ͳWebΞϓϦέʔγϣϯͩͱAngular.jsͷํ͕޲͍ͯ
    ͍Δ৔߹͕ଟ͍

    • Backbone.jsܥ͸Backbone.stickit Έ͍ͨͳσʔλόΠϯσΟϯάϥΠϒϥϦ
    ΋͋Δ͚ͲͲ͏ͯ͠΋ίʔυྔ͸ଟ͘ͳΓ͕ͪ
    http://blog.shinetech.com/2013/09/06/backbone-is-not-enough/

    View Slide

  10. Why Marionette?
    • ͸͡Ί͸Backbone.js͚ͩͰ࡞͍ͬͯͬͨ

    • SPAͳͷͰෳ਺ViewͰͷදࣔͷ੾Γସ͑ɺωετͨ͠Viewߏ଄Λ͍͍ײ͡ʹ
    ѻ͍͔ͨͬͨ

    • ↑Έ͍ͨͳ͜ͱΛ࣮૷ͯ͠Δͱ͖ʹMarionette.jsΛ஌Δ

    • ࣮૷ΛݟΔͱࣗ෼ͷ΍Γ͔ͨͬͨ͜ͱ͕͍͍ײ͡ʹ࣮૷͞Ε͍ͯͨͷͰಋೖ

    • Marionette.jsྲྀʹ৐͔ͬΔ͜ͱͰϝϞϦϦʔΫͳͲΛগ͠Ͱ΋ҙࣝ͠ͳ͍Ͱ։
    ൃ͔ͨͬͨ͠

    View Slide

  11. View of Marionette

    View Slide

  12. View of Marionette
    • Marionette͸ViewपΓ͕ΩϞ

    • RegionɺLayoutʹΑΔ֊૚Խͨ͠Viewͷ࢓૊ΈΛఏڙ

    • CollectionView, CompositeViewʹΑΔViewͷू߹Λ؅ཧ͢Δ࢓૊Έ

    • modelEvents, collectionEventsʹΑΔModel΍CollectionͷΠϕϯτߪಡͷ࢓૊Έ

    • onShow, onRenderɺonBeforeRenderͳͲ֤छΠϕϯτϋϯυϥ

    • ui, templateHelpers, serializeData ͳͲͪΐͬͱͨ͠ศརػೳ

    View Slide

  13. Nested View

    View Slide

  14. Nested View
    • SinglePageAppͰ͸ϖʔδભҠͰ͸ͳ͘Viewͷ֤ཁૉ͕ঢ়ଶʹΑͬͯͦΕͧ
    Εಠཱͯ͠มԽ͍ͯ͘͠
    ϝχϡʔͷཁૉ
    ϝΠϯͷཁૉ
    αϒͷཁૉ
    ϝχϡʔͷཁૉ
    ϝΠϯͷཁૉ
    αϒͷཁૉ
    ֊૚Խͨ͠ViewΛ؅ཧ
    ͢Δ࢓૊Έ͕ཉ͘͠ͳΔ

    View Slide

  15. Marionette.RegionManager and Marionette.Region
    • ཁૉ͝ͱͷViewΛRegionͱ͍͏୯ҐͰ؅ཧΛͯ͘͠ΕΔ

    • RegionʹViewΛ௥Ճ͢Δ࣌ɺ͢ͰʹผͷView͕௥Ճ͞Ε͍ͯΕ͹ݹ͍Viewͷ
    ޙ࢝຤Λ͔ͯ͠Β৽͍͠ViewΛ௥Ճͯ͘͠ΕΔ

    • Regionʹ౉͢Viewͷcloseॲཧ͸ߟ͑ͯͳͯ͘Α͘ͳΔ

    • MarionetteLayoutͱMarionetteApplicationͰRegionMangerΛ࢖͏͜ͱ͕ग़དྷ
    Δ

    View Slide

  16. About render
    • renderϝιου͸ɺItemView΍LayoutɺCollectionViewʹ࣮૷͞Ε͍ͯΔͷͰ
    جຊతʹ͸ࣗ෼Ͱ࣮૷͢Δඞཁ͸ͳ͍

    • ࢦఆ͞ΕͨtemplateʹtoJSON()ͨ͠஋Λ౉͢ͳͲΛ΍ͬͯ͘Ε͍ͯΔ

    • render࣌ʹ΍Γ͍ͨॲཧ͕͋Ε͹ɺ”render”΍”show”Πϕϯτ͕ൃߦ͞ΕΔͷ
    ͰonRender΍onShowͰ࣮૷͢Δ

    • RegionΛ࢖͍ͬͯΔ৔߹ɺonRenderͷ࣌఺Ͱ͸$elʹ௥Ճ͞Ε͍ͯΔ͚ͩͰ
    DOMπϦʔʹ͸·ͩ௥Ճ͞Ε͍ͯͳ͍ͷͰɺཁૉͷߴ͞Λऔಘ͢ΔͳͲͨ͠
    ͍৔߹͸onShowʹ࣮૷͢Δ

    View Slide

  17. Sample of Marionette.Layout and Region
    • LayoutViewʹ֤DOMཁૉΛRegionͱͯ͠ొ࿥͢Δ͜ͱʹΑͬͯɺViewͷ੾Γ
    ସ͑Λαϙʔτͯ͘͠ΕΔ
    #menu
    #main
    #sub
    var layout = new Marionette.Layout()!
    layout.addRegions({!
    menu: “#menu”,!
    main: “#main”,!
    sub: “#sub”,!
    });!
    !
    // ΠϯελϯεԽͨ͠ViewΛshowϝιουʹ౉͚ͩ͢!
    // render͸ࣗಈతʹݺΜͰ͘ΕΔ!
    layout.menu.show(new MyApp.MenuView());!
    layout.main.show(new MyApp.MainView());!
    layout.sub.show(new MyApp.SubView());!
    :!
    :!
    // લͷView͸close͞Εͯ৽͍͠View͕දࣔ͞ΕΔ!
    layout.main.show(new MyApp.OtherView());

    View Slide

  18. Implement of Marionette.Region#show
    show: function(view){!
    !
    this.ensureEl();!
    !
    var isViewClosed = view.isClosed || _.isUndefined(view.$el);!
    var isDifferentView = view !== this.currentView;!
    // ผͷViewΛදࣔ͢Δ࣌͢Ͱʹදࣔ͞Ε͍ͯΔViewΛclose͢Δ͜ͱͰޙ࢝຤͢Δ!
    if (isDifferentView) {!
    this.close();!
    }!
    view.render();!
    if (isDifferentView || isViewClosed) {!
    this.open(view);!
    }!
    !
    this.currentView = view;!
    // RegionͱViewͷshowΠϕϯτΛൃߦ͢Δ!
    Marionette.triggerMethod.call(this, "show", view);!
    Marionette.triggerMethod.call(view, "show");!
    },
    • https://github.com/marionettejs/backbone.marionette/blob/master/src/
    marionette.region.js

    View Slide

  19. Implement of Marionette.ItemView#render
    render: function(){!
    this.isClosed = false;!
    !
    this.triggerMethod("before:render", this);!
    this.triggerMethod("item:before:render", this);!
    !
    var data = this.serializeData();!
    data = this.mixinTemplateHelpers(data);!
    !
    var template = this.getTemplate();!
    var html = Marionette.Renderer.render(template, data);!
    !
    this.$el.html(html);!
    this.bindUIElements();!
    !
    this.triggerMethod("render", this);!
    this.triggerMethod("item:rendered", this);!
    !
    return this;!
    },
    • https://github.com/marionettejs/backbone.marionette/blob/master/src/
    marionette.itemview.js

    View Slide

  20. Implement of Marionette.View#close
    close: function(){!
    // ͢Ͱʹดͯ͡Δ৔߹͸Կ΋͠ͳ͍!
    if (this.isClosed) { return; }!
    !
    // onBeforeCloseϝιουͰfalseฦͨ͠ͱ͖͸ด͡Δͷ΍ΊΔ!
    var shouldClose = this.triggerMethod("before:close");!
    if (shouldClose === false){!
    return;!
    }!
    !
    // closeΠϕϯτൃߦͯ͠uiʹbind͞ΕͯΔDOMΛ࡟আͯ͠viewΛ࡟আͯ͠Δ!
    this.isClosed = true;!
    this.triggerMethod(“close");!
    !
    this.unbindUIElements();!
    !
    this.remove();!
    },
    • https://github.com/marionettejs/backbone.marionette/blob/master/src/
    marionette.view.js

    View Slide

  21. View Structure

    View Slide

  22. View Structure
    • Marionette.Application͕RegionManagerΛ͍࣋ͬͯΔͷͰɺ
    Application(Region) > Layout > (Layout or ItemView or CollectionView or
    CompositeViewͱ͍͏ߏ੒ʹ͢Δ

    • Regionʹ௥Ճ͢ΔLayoutͰViewʹඞཁͳModel΍CollectionͷfetchΛߦ͓ͬͯ
    ͘

    • ࢠViewΛඳը͢Δͱ͖ʹ͸͢Ͱʹσʔλ͕ἧ͍ͬͯΔํ͕ίʔυ͕ॻ͖΍
    ͍͢

    • LayoutҎԼͷView΋ඞཁͰ͋Ε͹Layoutʹͯ͠͞Βʹ෼ׂ͢Δ

    View Slide

  23. View Structure
    #menu (Region)
    #main (Region)
    Marionette Application
    LayoutView
    CollectionView
    ItemView
    ItemView
    ItemView
    ItemView
    LayoutViewͰitemViewͱ
    CollectionViewͰඞཁͳmodel΍
    collectionΛfetch͓ͯ͘͠

    View Slide

  24. View Structure
    // Applicationͷmain RegionʹLayoutViewΛ௥Ճ͢Δ!
    App.main.show(new LayoutView());
    // in LayoutView!
    onRender: function() {!
    var _this = this;!
    var model = new SomeModel();!
    var collection = new SomeCollection();!
    !
    // modelͱcollectionΛfetchͯ͠itemͱcollectionʹViewΛ௥Ճ!
    model.fetch().done(function() {!
    _this.item.show(new ItemView(model: model);!
    });!
    collection.fetch().done(function() {!
    _this.list.show(new CollectionView(collection: collection);!
    });!
    !
    // or!
    //$.when(model.fetch(), collection.fetch()).done(function(){!
    // _this.item.show(new ItemView(model: model);!
    // _this.list.show(new CollectionView(collection: collection);!
    //});!
    };!

    View Slide

  25. DOM Manipulation

    View Slide

  26. triggers
    MyView = Marionette.ItemView.extend({!
    !
    // :۠੾ΓΛCamelCaseʹͯ͠onΛ໊͚ͭͨલͷϝιου͕͋Ε͹ݺΜͰ͘ΕΔ!
    // “foo:bar” => onFooBar!
    triggers: {!
    “click .change-name”: “change:name”!
    },!
    !
    onChangeName: function() { … },!
    });
    • DOMΠϕϯτΛtriggersʹ·ͱΊͯॻ͍͓ͯ͘͜ͱ͕ग़དྷͯɺ
    preventDefaultɺstopPropagation΋΍ͬͯ͘ΕΔ

    View Slide

  27. BindUIElements
    MyView = Marionette.ItemView.extend({!
    !
    // View͕৮ΔDOM͕͜͜Ͱఆٛ͞ΕͯΘ͔Γ΍͍͢͠!
    // ม਺໊:“ηϨΫλࢦఆ”!
    ui: {!
    name: “.name”!
    },!
    !
    // triggersͷதͰ΋࢖͑Δ!
    triggers: {!
    “click @ui.name”: “change:name”!
    }!
    !
    someMethod: function() {!
    // ͜Μͳײ͡Ͱ࢖͏!
    this.ui.name.hide()!
    }!
    });
    • uiͱͯ͠ηϨΫλͱม਺໊Λఆ͓ٛͯ͘͠ͱthis.xxxͱ͍͏ܗࣜͰΞΫηε͢
    Δ͜ͱ͕ग़དྷΔ

    View Slide

  28. Event

    View Slide

  29. modelEvents, collectionEvents, itemEvents…
    MyView = Marionette.ItemView.extend({!
    !
    // Viewʹඥ͚͍ͮͯΔModelͷΠϕϯτΛߪಡ͢Δ!
    // space۠੾ΓͰෳ਺ͷϝιουΛొ࿥͢Δ͜ͱ΋ग़དྷΔ!
    // collectionEvents΋͋Δ!
    modelEvents: {!
    “change”: “onChangeModel otherMethod”!
    },!
    onChangeModel: function() { … },!
    otherMethod: function() { … },!
    });
    • modelEvents, collectionEvents, itemEventsͱ͍ͬͨΦϒδΣΫτΛఆٛͯ͠
    ͓͘͜ͱͰɺlistenTo΍stopListeningͱ͔ҙࣝͤͣʹ؆୯ʹΠϕϯτΛߪಡ͢
    Δ͜ͱ͕ग़དྷΔ

    View Slide

  30. View Events
    • “dom:refresh”,“before:render”, ”render”,”close”ͳͲଟ͘ͷΠϕϯτ͕ൃߦ͞
    ΕΔͷͰɺMarionette͕ఏڙͯ͘͠ΕΔػೳҎ֎ͷ͜ͱ͕͍ͨ͠৔߹͸ɺ͜Ε
    ΒͷΠϕϯτΛϑοΫ࣮ͯ͠૷͢Δͱ͍͍

    • CollectionViewͳͲͰ͸ࢠViewͷΠϕϯτΛ”itemview:xxx”ͱͯ͠ड͚औΔ͜
    ͱ͕ग़དྷΔ

    • itemEventsʹఆٛͨ͠ํ͕Θ͔Γ΍͍͚͢Ͳ

    View Slide

  31. My Custom Events

    View Slide

  32. appEvents?? (My Custom Implement)
    • ApplicationҎԼͷRegionΛ·͍ͨͰ΍ΓͱΓΛ͍ͨ͜͠ͱ͕͋ͬͨͷͰ࣮૷
    ͯ͠ΈͨɻApplicationʹlistenTo͢Δ͜ͱͰผRegionؒͰͷViewͷ΍ΓͱΓΛ
    Մೳʹ͢Δ

    • ↓ͷIssueͱجຊతʹ΍Γ͍ͨ͜ͱ͸ಉ͡

    • ʮSimplyfing listening to App.vent in viewsʯ

    • https://github.com/marionettejs/backbone.marionette/issues/826

    • events, triggers, modelEventsͳͲҧͬͯɺ਌ࢠܑఋؔ܎ʹͳ͍ཁૉؒͳͷ
    Ͱ٫Լ͞ΕͯΔ

    View Slide

  33. appEvents?? (My Custom Implement)
    MyView = BaseView.extend({!
    // ߪಡ͢Δ!
    appEvents: {!
    “change:menu”: “change:menu”!
    },!
    onChangeMenu: function() {!
    …!
    }!
    });
    // ࣮૷!
    // App.trigger(“xxxx”)Ͱൃߦ͢Δ!
    // modelEventsΈ͍ͨʹappEventsͰߪಡ͢Δ!
    BaseView = Marionette.Layout.extend({!
    delegateEvents: function(events){!
    Marionette.Layout.prototype.delegateEvents.call(this, events);!
    Marionette.bindEntityEvents(this, App, Marionette.getOption(this, “appEvents”));!
    },!
    undelegateEvents: function(){!
    Marionette.Layout.prototype.undelegateEvents.call(this);!
    Marionette.bindEntityEvents(this, App, Marionette.getOption(this, “appEvents”));!
    },!
    });

    View Slide

  34. Template

    View Slide

  35. serializeData and templateHelpers
    MyView = Marionette.ItemView.extend({!
    !
    // σϑΥϧτͰthis.model͔this.collection͕templateʹ౉͞ΕΔͷΛม͍͑ͨ৔߹ʹ࢖͏!
    serializeData: function() {!
    return {!
    my: my.toJSON(),!
    notifications: notifications.toJSON(),!
    };!
    },!
    // templateͷதͰ࢖͍͍ͨؔ਺Λొ࿥ग़དྷΔ(serializeDataͱmerge͞ΕΔ)!
    // ൚༻తʹ࢖͏΋ͷ͸HandlebarsͩͱHandlebars.registerHelper࢖͏ͱ͍͍!
    templateHelpers: {!
    return {!
    notificationMessage: function(notification) {!
    // this͸serializeDataͷ஋!
    notification.message.replace(/__NAME__/g, this.my.name);!
    },!
    };!
    },!
    });
    • templateʹ౉͢஋ΛΧελϚΠζ͍ͨ͠৔߹ʹ࢖͏

    View Slide

  36. PreCompiled template
    // Renderer.renderΛΦʔόʔϥΠυ͢Δ͜ͱͰprecompileͨ͠templateΛ࢖͏!
    Backbone.Marionette.Renderer.render = function(template, data){!
    return JST[template](data);!
    };!
    MyView = Marionette.ItemView.extend({!
    template:‘path/to/template’,!
    });!
    !
    or!
    !
    // templateʹ௚઀precompile͞ΕͨtemplateΛ౉͍ͯ͠Δ!
    MyView = Marionette.ItemView.extend({!
    template: JST[‘path/to/template’],!
    });
    • templateʹ௚઀౉ͨ͠ΓɺMarionette.Renderer.renderΛΦʔόʔϥΠυͨ͠
    Γ͢Δ͜ͱͰՄೳ

    View Slide

  37. ListView

    View Slide

  38. Marionette.CollectionView And CompositeView
    • Marionette.ViewΛܧঝ͍ͯͯ͠ɺCollectionΛItemViewΛ࢖ͬͯ܁Γฦ͠දࣔ
    ͢Δͱ͖ʹ࢖͏ViewɻitemViewΛඞͣ࣋ͭ

    • template͸ఆٛग़དྷͳ͍ͷͰtableͳͲ୯७ͳ܁Γฦ͠Ͱ͸ͳ͍ͱ͖͸
    CompositeViewΛ࢖͏

    • CompositeView͸CollectionViewΛܧঝ͍ͯ͠Δ

    • Collection͕ۭͷ৔߹ʹ࢖ΘΕΔemptyViewΛఆٛग़དྷΔ

    • Collectionͷadd, remove, resetΠϕϯτ΋listen͍ͯͯ͠ɺViewͷߋ৽Λ΍ͬ
    ͯ͘ΕΔ

    View Slide

  39. Example of Marionette.CollectionView
    MyItemsView = Marionette.CollectionView.extend({!
    // tagΛࢦఆ͠ͳ͍ͱۭͷdiv͕࡞ΒΕΔͷͰɻ!
    // MyItemRowViewͷtagName͸”li”ʹͳΔ!
    tagName: “ul”,!
    itemView: MyItemRowView,!
    emptyView: EmptyItemView,!
    // itemEventsͱͯ͠!
    itemViewͷΠϕϯτΛߪಡ͢Δ͜ͱ͕ग़དྷΔ (>= 1.5.0)!
    itemEvents: {!
    “change:tab”: “onItemViewChangeTab”!
    },!
    onItemViewChangeTab: function(){ … },!
    });!
    !
    var layout = new Marionette.Layout();!
    // myItemsͷ֤ཁૉΛMyItemRowViewΛ࢖ͬͯඳը͢Δ!
    // (ۭͷ৔߹͸EmptyItemView͕ඳը͞ΕΔ)!
    layout.myItems.show( new MyItemsView(collection: myItems) );

    View Slide

  40. Example of Marionette.CompositeView
    MyItemsView = Marionette.CompositeView.extend({!
    template: “composite/items”!
    itemViewContainer: “#item-body”,!
    itemView: MyItemRowView,!
    });!
    !
    var layout = new Marionette.Layout();!
    layout.myItems.show( new MyItemsView(collection: myItems) );

    View Slide

  41. Application.module

    View Slide

  42. Application.module
    • ApplicationҎԼʹఆٛग़དྷΔ໊લۭؒͷΑ͏ͳ΋ͷ

    • View.LayoutͳͲ.۠੾ΓͰɺ͢Ͱʹఆٛ͞Ε͍ͯΔ͔ؾʹ͢Δ͜ͱͳ͘ఆٛग़
    དྷΔ

    • App.start()͢ΔͱAppʹඥ෇͍͍ͯΔModule΋start()͞ΕΔɻ(ݸผʹstartɺ
    stop͢Δ͜ͱ΋ग़དྷΔ)

    View Slide

  43. Application.module
    MyApp = new Marionette.Application();!
    !
    // ఆٛͨ͠Ϟδϡʔϧɺݺͼग़͠ݩϞδϡʔϧɺBackbone, Marionette, $, _ ͷॱͰ౉͞ΕΔ!
    MyApp.module(“Model”, function(Model, App, Backbone, Marionette, $, _) {!
    Model.My = Backbone.Model.extend({});!
    }); !
    !
    // View͕ఆٛ͞Εͯͳ͚Ε͹ࣗಈతʹఆٛ͞ΕΔ!
    // defaultͰఆٛ͞Ε͍ͯΔҾ਺Ҏ֎ʹ΋͞Βʹ౉͢͜ͱ͕ग़དྷΔ!
    MyApp.module(“View.Layout”, function(Layout, App, Backbone, Marionette, $, _, w) {!
    Layout.My = Marionette.Layout.extend({});!
    }, window); !
    !
    !
    // MyAppҎԼͷModule͕ಡΈࠐ·ΕΔ!
    MyApp.start()

    View Slide

  44. Other Components

    View Slide

  45. Other Components
    • ৭ʑ͋Δ͚ͲɺViewҎ֎͸ͦ͜·ͰॏཁͰͳ͍ͷͰলུ…

    • Backbone. Wreqr ʹఆٛ͞Ε͍ͯΔ΋ͷ͕ͦͷ··࢖͑ΔΑ͏ʹͳ͍ͬͯͨ
    Γ͢Δ

    • https://github.com/marionettejs/backbone.wreqr

    View Slide

  46. Other TIPS

    View Slide

  47. Generated HTML by server side
    • αʔόʔαΠυͰHTMLΛੜ੒͢ΔΑ͏ͳΞϓϦͷ৔߹͸ɺ
    Marionette.Region#attachView Λ࢖͏͜ͱͰcurrentView΁ͷׂΓ౰͚ͯͩΛ
    ߦ͏͜ͱ͕ग़དྷΔ

    • https://github.com/marionettejs/backbone.marionette/blob/master/src/
    marionette.region.js
    // currentViewʹviewΛಥͬࠐΜͰ͍Δ͚ͩ!
    attachView: function(view){!
    this.currentView = view;!
    },

    View Slide

  48. Render animation
    • View੾ସ࣌ʹΞχϝʔγϣϯ͍ͨ͠৔߹͸Marionette.Region#openΛΦʔ
    όʔϥΠυ͢Δ

    • https://github.com/marionettejs/backbone.marionette/blob/master/src/
    marionette.region.js
    // defaultͷopenͷ࣮૷!
    open: function(view){!
    this.$el.empty().append(view.el);!
    },

    View Slide

  49. Summary
    • MarionetteΛ࢖͍Marionette͕ఏڙ͢Δ࢓૊Έʹ৐͔࣮ͬͬͯ૷͢Δ͜ͱͰɺ
    Viewͷޙ࢝຤ͳͲҙࣝ͢Δ͜ͱ͕গͳ͘ͳΔ

    • BackboneͷViewͩͱ੍໿͕ͳ͍ͷͰࣗ༝ʹͳΓ͕ͪͳViewपΓͷ࣮૷͕ڞ௨Խ
    ͞Εͯɺଞͷਓ͕ॻ͍ͨίʔυ͕ಡΈ΍͘͢ͳΔ

    • modelEvents, triggers, ui ͳͲͰఆٛ͞ΕΔ͜ͱͰViewͷ໾ׂ͕Θ͔Γ΍͍͢

    • BackboneͷԆ௕ઢ্ʹ͋ΔϑϨʔϜϫʔΫͳͷͰɺBackboneΛ࢖͍ͬͯΕ͹ཧ
    ղ͢Δͷ͸೉͘͠ͳ͍ɻ

    • ιʔε͕Θ͔Γ΍͍͢ͷͰษڧʹͳΔ

    View Slide

  50. Any Question?
    !

    View Slide