Bindung an ein Backbone-Modell zu einer Marionette ItemView - blocking .fetch()?
Dies ist ein 2 Teil in Frage. 1) gibt es eine bessere Methode für die Wiedergabe eines Modells zu einer Ansicht asynchron? Ich bin aktuell den ajax-request mit der fetch
Methode in das Modell (obwohl ich ' m nannte es explizit auf initilization), dann rendering der Vorlagen-Ansicht verwenden Sie eine Anwendung-Ereignis vent
, die veröffentlicht wird, von innen das Modell nach der parse
- Methode aufgerufen wird. Cool, aber wackelig? 2) Würde eine Sperrung fetch
Methode von nutzen sein, und ist es möglich?
Die Anwendung stellt diese auf der Seite:
layout
navbar
index
Dann holt Sie das Modell und rendert diese:
layout
navbar
thing
1
something
somethingelse
Aber, wenn ich nicht verwenden, die vent
auslösen, ist es (erwartungsgemäß) macht:
layout
navbar
thing
1
null
null
Den html-templates:
<!-- Region: NavBar -->
<script type="text/template" id="template-navbar">
<div id="navbar">
navbar
</div>
</script>
<!-- View: IndexView -->
<script type="text/template" id="template-index">
<div id="index">
index
</div>
</script>
<!-- View: ThingView -->
<script type="text/template" id="template-thing">
<div id="thing">
thing<br/>
<%= id %><br/>
<%= valOne %><br/>
<%= valTwo %><br/>
</div>
</script>
<!-- Region -->
<div id="default-region">
<!-- Layout -->
<script type="text/template" id="template-default">
layout
<div id="region-navbar">
</div>
<div id="region-content">
</div>
</script>
</div>
app.js:
window.App = { }
# Region
class RegionContainer extends Backbone.Marionette.Region
el: '#default-region'
# Called on the region when the view has been rendered
onShow: (view) ->
console.log 'onShow RegionContainer'
App.RegionContainer = RegionContainer
# Layout
class DefaultLayout extends Backbone.Marionette.Layout
template: '#template-default'
regions:
navbarRegion: '#region-navbar'
contentRegion: '#region-content'
onShow: (view) ->
console.log 'onShow DefaultLayout'
App.DefaultLayout = DefaultLayout
# NavBar (View)
class NavBar extends Backbone.Marionette.ItemView
template: '#template-navbar'
initialize: () ->
console.log 'init App.NavBar'
App.NavBar = NavBar
# Index View
class IndexView extends Backbone.Marionette.ItemView
template: '#template-index'
initialize: () ->
console.log 'init App.IndexView'
App.IndexView = IndexView
# Thing View
class ThingView extends Backbone.Marionette.ItemView
template: '#template-thing'
model: null
initialize: () ->
console.log 'init App.ThingView'
events:
'click .test_button button': 'doSomething'
doSomething: () ->
console.log 'ItemView event -> doSomething()'
App.ThingView = ThingView
# Thing Model
class Thing extends Backbone.Model
defaults:
id: null
valOne: null
valTwo: null
url: () ->
'/thing/' + @attributes.id
initialize: (item) ->
console.log 'init App.Thing'
@fetch()
parse: (resp, xhr) ->
console.log 'parse response: ' + JSON.stringify resp
# resp: {"id":"1","valOne":"something","valTwo":"somethingelse"}
@attributes.id = resp.id
@attributes.valOne = resp.valOne
@attributes.valTwo = resp.valTwo
console.log 'Thing: ' + JSON.stringify @
@
App.MyApp.vent.trigger 'thingisdone'
App.Thing = Thing
# App
$ ->
# Create application, allow for global access
MyApp = new Backbone.Marionette.Application()
App.MyApp = MyApp
# RegionContainer
regionContainer = new App.RegionContainer
# DefaultLayout
defaultLayout = new App.DefaultLayout
regionContainer.show defaultLayout
# Views
navBarView = new App.NavBar
indexView = new App.IndexView
# Show defaults
defaultLayout.navbarRegion.show navBarView
defaultLayout.contentRegion.show indexView
# Allow for global access
App.defaultRegion = regionContainer
App.defaultLayout = defaultLayout
# Set default data for MyQpp (can't be empty?)
data =
that: 'this'
# On application init...
App.MyApp.addInitializer (data) ->
console.log 'init App.MyApp'
# Test
App.modelViewTrigger = ->
console.log 'trigger ajax request via model, render view'
App.MyApp.vent.trigger 'show:thing'
App.timeoutInit = ->
console.log 'init timeout'
setTimeout 'App.modelViewTrigger()', 2000
App.timeoutInit()
# Event pub/sub handling
App.MyApp.vent.on 'show:thing', ->
console.log 'received message -> show:thing'
thing = new App.Thing(id: '1')
App.thingView = new App.ThingView(model: thing)
# I should be able to do this, but it renders null
# App.defaultLayout.contentRegion.show App.thingView
# Testing to see if I could pub from inside model..yes!
App.MyApp.vent.on 'thingisdone', ->
console.log 'received message -> thingisdone'
App.defaultLayout.contentRegion.show App.thingView
MyApp.start data
InformationsquelleAutor | 2012-05-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aus einer sehr einfachen Sicht -, Wurf-neben dem spezifischen Beispiel, haben Sie zur Verfügung gestellt, hier ist, wie würde ich Vorgehen, das problem und die Lösung.
Ein Allgemeines Problem /Lösung
Hier ist eine Allgemeine version des Problems:
Ist dies ziemlich einfach. Befestigen Sie das Modell zu der Ansicht, vor dem abrufen der Daten verwenden Sie dann die "sync" - Ereignis des Modells zum Rendern der Ansicht:
Dinge zu beachten:
Ich bin einrichten das Modell mit seiner id und den view mit dem Modell vor dem Aufruf
fetch
auf das Modell. Dies ist notwendig, um zu verhindern, dass eine race-condition zwischen dem laden der Daten und das Rendern der anzeigen.Habe ich angegeben generic Rückgrat Sachen hier. Marionette wird in der Regel die gleiche Arbeit, aber das rendering für Sie.
Ihre Spezifischen Bedürfnisse
Sperrung Holen
Schlechte Idee, alle um Sie herum. Versuchen Sie nicht, es.
Einer Sperrung Holen wird Ihre Anwendung komplett nicht mehr reagiert, bis die Daten vom server zurückgegeben hat. Dies manifestiert sich als eine Anwendung, die schlecht und friert jedes mal, wenn der Benutzer versucht, etwas zu tun.
Den Schlüssel nicht dabei ist nutzen-Ereignisse und gewährleistet, dass die Ereignisse konfiguriert werden, bevor Sie tatsächlich machen, der asynchrone Aufruf, wie in meinem Standardbeispiel.
Und rufen Sie nicht die fetch innerhalb des Modells die Initialisierung. Das ist ärger, da Sie nicht in der Lage sein, alle Ansichten oder Ereignisse vor der fetch passiert. Ich bin mir ziemlich sicher, dies zu lösen, wird der Großteil der Probleme, die Sie aufgrund der asynchronen Aufruf.
Ereignisse Zwischen View-Und Modell -
Zuerst möchte ich vermeiden, mit
MyApp.vent
für die Kommunikation zwischen dem Modell und der view-Instanz. Der Blick bereits einen Verweis auf das Modell, so sollten Sie direkt miteinander kommunizieren.In anderen Worten, das Modell sollte direkt das Ereignis ausgelöst und die Ansicht zu hören sollte die Veranstaltung auf dem Modell. Dies funktioniert in der gleichen Weise wie mein einfaches Beispiel, aber Sie können Ihre Modell-trigger jede Veranstaltung, die Sie wollen zu jeder Zeit.
Ich würde auch sicher sein, um die Verwendung
bindTo
Funktion der Marionette, die Ansichten, um Ihnen die Reinigung der Ereignisse, wenn die Ansicht geschlossen.Andere Elemente
Gibt es einige andere Elemente, die ich denke, sind was zu einigen Problemen, oder führt zu sonderbaren Situationen, die Probleme verursachen wird.
Zum Beispiel, Sie haben zu viel passiert, in der DOMReady-event:
$ ->
Es ist nicht, dass Sie zu viel code ausgeführt wird, von dieser Veranstaltung, aber Sie haben zu viel code definiert im Rahmen dieser Veranstaltung. Sollten Sie nicht haben, etwas zu tun mehr als das:
Definieren nicht Ihre Marionette.Application-Objekt in diesem Ereignis-Rückruf, entweder. Diese sollten definiert werden, auf seine eigene, so dass Sie einrichten können Ihre Initialisierungen außerhalb von DOMReady Rückruf, und dann lösen Sie Sie mit der
app.start()
nennen.Werfen Sie einen Blick auf die BBCloneMail Beispiel-Anwendung für ein Beispiel-rendering ein layout und füllen Ihren Regionen nach dem laden von Daten und die externen templates:
Quelle: https://github.com/derickbailey/bbclonemail
live-app: http://bbclonemail.heroku.com/
Glaube ich nicht, ich habe direkt die Beantwortung Ihrer Fragen die, wie Sie vielleicht möchten, aber die Ideen, die ich bin präsentiert, sollte Sie auf die Antwort, die Sie brauchen. Ich hoffe, es hilft zumindest. 🙂
wie verhindern Sie die Marionette aus dem Rendern der Ansicht, bevor das Modell geholt? Da das Modell bereits enthält eine id, Marionette versucht zu machen, es sofort?
Hey Derick — würde man noch berücksichtigen, das ein up-to-date best practice zur Strukturierung von fetch + macht? Neugierig wie ich versucht habe diese ein paar verschiedene Möglichkeiten in meinem app und bin neugierig, was ist Derick Genehmigten®.. 😉
Ich würde notieren Sie sich das Datum dieser Antwort. Insbesondere in v1.0.0-rc3 Marionette, bindTo wurde ersetzt mit der listenTo-Methode. github.com/marionettejs/backbone.marionette/blob/master/...
InformationsquelleAutor Derick Bailey
Sehen Derick neuen Vorschlag zur Bewältigung dieses gemeinsamen Problems an: https://github.com/marionettejs/backbone.marionette/blob/master/upgradeGuide.md#marionetteasync-is-no-longer-supported
Kurz, verschieben Sie den asynchronen code Weg von Ihrem Blick auf, was bedeutet, Sie müssen Sie mit Modellen, deren Daten bereits geladen wurden. Aus dem Beispiel im Marionetten-upgrade-guide:
InformationsquelleAutor Elliot Brightside