Marionette.js in Single Page Application

45daf58c77e9dbbab5a1c8a5afc7ac5c?s=47 koba04
January 21, 2014

Marionette.js in Single Page Application

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

45daf58c77e9dbbab5a1c8a5afc7ac5c?s=128

koba04

January 21, 2014
Tweet

Transcript

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

  2. Agenda • Single Page Applicationʹ͓͍ͯMarionette.jsΛ࢖͏ཧ༝ • Marionette.jsͷViewपΓͷߏ଄ʹ͍ͭͯ • Marionette.jsͷศརͳػೳͨͪ

  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.
  4. Backbone (1.1.0) • http://backbonejs.org/ • ΞϓϦέʔγϣϯΛModel, Collection, ViewͳͲͷཁૉͰߏ଄Խͯ͘͠ΕΔϑ ϨʔϜϫʔΫ •

    Backbone.EventsʹΑΔObserverύλʔϯͰͷ΍ΓͱΓ • ࠷௿ݶͷػೳ͚͕ͩఏڙ͞Ε͍ͯΔͷͰ͜Ε͚ͩͰSPAΛͭ͘Ζ͏ͱ͢Δͱɺ ͦͷ্ʹ΋͏Ұ૚ϑϨʔϜϫʔΫΛߏஙͤ͟ΔΛಘͳ͍ • ϝϞϦϦʔΫɺZombieViewා͍… • SPAͷ৔߹ɺϝϞϦϦʔΫ͸க໋త
  5. Marionette (1.5.1) • http://marionettejs.com/ • Backbone.jsΛϕʔεʹViewपΓΛத৺ʹڧԽͨ͠ϑϨʔϜϫʔΫ • BackboneܥͷϥΠϒϥϦͷதͰ࠷΋Star͞Ε͍ͯΔ • Backbone.jsΛϕʔεʹ࣮ͨ͠૷ʹͳ͍ͬͯΔͷͰιʔε͕ಡΈ΍͍͢͠ɺυ

    Ωϡϝϯτ΋Θ͔Γ΍͍͢ • https://leanpub.com/marionette-gentle-introduction
  6. http://backplug.io

  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.
  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
  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/
  10. Why Marionette? • ͸͡Ί͸Backbone.js͚ͩͰ࡞͍ͬͯͬͨ • SPAͳͷͰෳ਺ViewͰͷදࣔͷ੾Γସ͑ɺωετͨ͠Viewߏ଄Λ͍͍ײ͡ʹ ѻ͍͔ͨͬͨ • ↑Έ͍ͨͳ͜ͱΛ࣮૷ͯ͠Δͱ͖ʹMarionette.jsΛ஌Δ •

    ࣮૷ΛݟΔͱࣗ෼ͷ΍Γ͔ͨͬͨ͜ͱ͕͍͍ײ͡ʹ࣮૷͞Ε͍ͯͨͷͰಋೖ • Marionette.jsྲྀʹ৐͔ͬΔ͜ͱͰϝϞϦϦʔΫͳͲΛগ͠Ͱ΋ҙࣝ͠ͳ͍Ͱ։ ൃ͔ͨͬͨ͠
  11. View of Marionette

  12. View of Marionette • Marionette͸ViewपΓ͕ΩϞ • RegionɺLayoutʹΑΔ֊૚Խͨ͠Viewͷ࢓૊ΈΛఏڙ • CollectionView, CompositeViewʹΑΔViewͷू߹Λ؅ཧ͢Δ࢓૊Έ

    • modelEvents, collectionEventsʹΑΔModel΍CollectionͷΠϕϯτߪಡͷ࢓૊Έ • onShow, onRenderɺonBeforeRenderͳͲ֤छΠϕϯτϋϯυϥ • ui, templateHelpers, serializeData ͳͲͪΐͬͱͨ͠ศརػೳ
  13. Nested View

  14. Nested View • SinglePageAppͰ͸ϖʔδભҠͰ͸ͳ͘Viewͷ֤ཁૉ͕ঢ়ଶʹΑͬͯͦΕͧ Εಠཱͯ͠มԽ͍ͯ͘͠ ϝχϡʔͷཁૉ ϝΠϯͷཁૉ αϒͷཁૉ ϝχϡʔͷཁૉ ϝΠϯͷཁૉ

    αϒͷཁૉ ֊૚Խͨ͠ViewΛ؅ཧ ͢Δ࢓૊Έ͕ཉ͘͠ͳΔ
  15. Marionette.RegionManager and Marionette.Region • ཁૉ͝ͱͷViewΛRegionͱ͍͏୯ҐͰ؅ཧΛͯ͘͠ΕΔ • RegionʹViewΛ௥Ճ͢Δ࣌ɺ͢ͰʹผͷView͕௥Ճ͞Ε͍ͯΕ͹ݹ͍Viewͷ ޙ࢝຤Λ͔ͯ͠Β৽͍͠ViewΛ௥Ճͯ͘͠ΕΔ • Regionʹ౉͢Viewͷcloseॲཧ͸ߟ͑ͯͳͯ͘Α͘ͳΔ

    • MarionetteLayoutͱMarionetteApplicationͰRegionMangerΛ࢖͏͜ͱ͕ग़དྷ Δ
  16. About render • renderϝιου͸ɺItemView΍LayoutɺCollectionViewʹ࣮૷͞Ε͍ͯΔͷͰ جຊతʹ͸ࣗ෼Ͱ࣮૷͢Δඞཁ͸ͳ͍ • ࢦఆ͞ΕͨtemplateʹtoJSON()ͨ͠஋Λ౉͢ͳͲΛ΍ͬͯ͘Ε͍ͯΔ • render࣌ʹ΍Γ͍ͨॲཧ͕͋Ε͹ɺ”render”΍”show”Πϕϯτ͕ൃߦ͞ΕΔͷ ͰonRender΍onShowͰ࣮૷͢Δ

    • RegionΛ࢖͍ͬͯΔ৔߹ɺonRenderͷ࣌఺Ͱ͸$elʹ௥Ճ͞Ε͍ͯΔ͚ͩͰ DOMπϦʔʹ͸·ͩ௥Ճ͞Ε͍ͯͳ͍ͷͰɺཁૉͷߴ͞Λऔಘ͢ΔͳͲͨ͠ ͍৔߹͸onShowʹ࣮૷͢Δ
  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());
  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
  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
  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
  21. View Structure

  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ʹͯ͠͞Βʹ෼ׂ͢Δ
  23. View Structure #menu (Region) #main (Region) Marionette Application LayoutView CollectionView

    ItemView ItemView ItemView ItemView LayoutViewͰitemViewͱ CollectionViewͰඞཁͳmodel΍ collectionΛfetch͓ͯ͘͠
  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);! //});! };!
  25. DOM Manipulation

  26. triggers MyView = Marionette.ItemView.extend({! ! // :۠੾ΓΛCamelCaseʹͯ͠onΛ໊͚ͭͨલͷϝιου͕͋Ε͹ݺΜͰ͘ΕΔ! // “foo:bar” =>

    onFooBar! triggers: {! “click .change-name”: “change:name”! },! ! onChangeName: function() { … },! }); • DOMΠϕϯτΛtriggersʹ·ͱΊͯॻ͍͓ͯ͘͜ͱ͕ग़དྷͯɺ preventDefaultɺstopPropagation΋΍ͬͯ͘ΕΔ
  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ͱ͍͏ܗࣜͰΞΫηε͢ Δ͜ͱ͕ग़དྷΔ
  28. Event

  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ͱ͔ҙࣝͤͣʹ؆୯ʹΠϕϯτΛߪಡ͢ Δ͜ͱ͕ग़དྷΔ
  30. View Events • “dom:refresh”,“before:render”, ”render”,”close”ͳͲଟ͘ͷΠϕϯτ͕ൃߦ͞ ΕΔͷͰɺMarionette͕ఏڙͯ͘͠ΕΔػೳҎ֎ͷ͜ͱ͕͍ͨ͠৔߹͸ɺ͜Ε ΒͷΠϕϯτΛϑοΫ࣮ͯ͠૷͢Δͱ͍͍ • CollectionViewͳͲͰ͸ࢠViewͷΠϕϯτΛ”itemview:xxx”ͱͯ͠ड͚औΔ͜ ͱ͕ग़དྷΔ

    • itemEventsʹఆٛͨ͠ํ͕Θ͔Γ΍͍͚͢Ͳ
  31. My Custom Events

  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ͳͲҧͬͯɺ਌ࢠܑఋؔ܎ʹͳ͍ཁૉؒͳͷ Ͱ٫Լ͞ΕͯΔ
  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”));! },! });
  34. Template

  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ʹ౉͢஋ΛΧελϚΠζ͍ͨ͠৔߹ʹ࢖͏
  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ΛΦʔόʔϥΠυͨ͠ Γ͢Δ͜ͱͰՄೳ
  37. ListView

  38. Marionette.CollectionView And CompositeView • Marionette.ViewΛܧঝ͍ͯͯ͠ɺCollectionΛItemViewΛ࢖ͬͯ܁Γฦ͠දࣔ ͢Δͱ͖ʹ࢖͏ViewɻitemViewΛඞͣ࣋ͭ • template͸ఆٛग़དྷͳ͍ͷͰtableͳͲ୯७ͳ܁Γฦ͠Ͱ͸ͳ͍ͱ͖͸ CompositeViewΛ࢖͏ •

    CompositeView͸CollectionViewΛܧঝ͍ͯ͠Δ • Collection͕ۭͷ৔߹ʹ࢖ΘΕΔemptyViewΛఆٛग़དྷΔ • Collectionͷadd, remove, resetΠϕϯτ΋listen͍ͯͯ͠ɺViewͷߋ৽Λ΍ͬ ͯ͘ΕΔ
  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) );
  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) );
  41. Application.module

  42. Application.module • ApplicationҎԼʹఆٛग़དྷΔ໊લۭؒͷΑ͏ͳ΋ͷ • View.LayoutͳͲ.۠੾ΓͰɺ͢Ͱʹఆٛ͞Ε͍ͯΔ͔ؾʹ͢Δ͜ͱͳ͘ఆٛग़ དྷΔ • App.start()͢ΔͱAppʹඥ෇͍͍ͯΔModule΋start()͞ΕΔɻ(ݸผʹstartɺ stop͢Δ͜ͱ΋ग़དྷΔ)

  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()
  44. Other Components

  45. Other Components • ৭ʑ͋Δ͚ͲɺViewҎ֎͸ͦ͜·ͰॏཁͰͳ͍ͷͰলུ… • Backbone. Wreqr ʹఆٛ͞Ε͍ͯΔ΋ͷ͕ͦͷ··࢖͑ΔΑ͏ʹͳ͍ͬͯͨ Γ͢Δ •

    https://github.com/marionettejs/backbone.wreqr
  46. Other TIPS

  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;! },
  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);! },
  49. Summary • MarionetteΛ࢖͍Marionette͕ఏڙ͢Δ࢓૊Έʹ৐͔࣮ͬͬͯ૷͢Δ͜ͱͰɺ Viewͷޙ࢝຤ͳͲҙࣝ͢Δ͜ͱ͕গͳ͘ͳΔ • BackboneͷViewͩͱ੍໿͕ͳ͍ͷͰࣗ༝ʹͳΓ͕ͪͳViewपΓͷ࣮૷͕ڞ௨Խ ͞Εͯɺଞͷਓ͕ॻ͍ͨίʔυ͕ಡΈ΍͘͢ͳΔ • modelEvents, triggers,

    ui ͳͲͰఆٛ͞ΕΔ͜ͱͰViewͷ໾ׂ͕Θ͔Γ΍͍͢ • BackboneͷԆ௕ઢ্ʹ͋ΔϑϨʔϜϫʔΫͳͷͰɺBackboneΛ࢖͍ͬͯΕ͹ཧ ղ͢Δͷ͸೉͘͠ͳ͍ɻ • ιʔε͕Θ͔Γ΍͍͢ͷͰษڧʹͳΔ
  50. Any Question? !