2012-09-24 33 views
7

He configurado mi aplicación para usar la arquitectura de enrutamiento de ember. Mis páginas de índice se parece a esto (por razones de simplicidad)Ember.js con Twitter Bootstrap Modal

script(type='text/x-handlebars', data-template-name='application') 
    div.container 
     {{outlet}} 

y mi aplicación brasa como esto

window.App = Em.Application.create({ 
    ApplicationController: Em.Controller.extend(), 
    ApplicationView: Ember.View.extend({ 
    templateName: 'application' 
    }), 
    Router: Em.Router.extend({ 
     root: Em.Route.extend({ 
     doHome: (router, event) -> 
      router.transitionTo('home') 
     doInbox: (router, event) -> 
      router.transitionTo('inbox') 
     doInboxModal: (router, event) -> 
      $("#inbox").modal "show" 
     home: Em.Route.extend({ 
      route: '/', 
      connectOutlets: (router, event) -> 
       router.get('applicationController').connectOutlet('home') 
     }), 
     inbox:Em.Route.extend({ 
      route: '/inbox', 
      connectOutlets: (router, event) -> 
       router.get('applicationController').connectOutlet('inbox') 
     }) 
    }) 
}) 

tengo el hogar y en la bandeja de entrada funciona bien, pero en primer lugar, que estoy haciendo jQuery en mi doInboxModal para mostrar la bandeja de entrada modal. Y si quiero tener un botón en la bandeja de entrada modal para ir a la página de la bandeja de entrada, no funcionará.

Entonces, la pregunta es, ¿cómo uso correctamente un Modal Bootstrap de Twitter con el enrutamiento de las brasas?

+0

que también publicó un simple ejemplo de un [Ejemplo modal de Twitter Bootstrap en Ember.js] (http://stackoverflow.com/questions/16879046/how-to-create-and-manage-a-twitter-bootstrap-modal-with-ember-js) –

Respuesta

7

Cuando ruta a una vista, llama a la modal en el didInsertElement, que cargará el modal..Assuming desea que el modal para cargar en la bandeja de entrada de vista

App.InboxView = Ember.View.extend({ 
    didInsertElement: function(){ 
    $("#my-modal").modal("show"); 
    } 
}) 

su router actualización:

window.App = Em.Application.create({ 
    ApplicationController: Em.Controller.extend(), 
    ApplicationView: Ember.View.extend({ 
    templateName: 'application' 
    }), 
    Router: Em.Router.extend({ 
    root: Em.Route.extend({ 
     doHome: (router, event) -> 
     router.transitionTo('home') 
     doInbox: (router, event) -> 
     router.transitionTo('inbox') 
     home: Em.Route.extend({ 
     route: '/', 
     connectOutlets: (router, event) -> 
      router.get('applicationController').connectOutlet('home') 
     }), 
     inbox:Em.Route.extend({ 
     route: '/inbox', 
     connectOutlets: (router, event) -> 
      router.get('applicationController').connectOutlet('inbox') 
     }) 
    }) 
}) 

Espero que esto ayude ...


Updated Answer
App.InboxView = Ember.View.extend({ 
    templateName: "inbox", 
    addNewEmail: function(){ 
    $("#my-modal").modal("show"); 
    }, 
    cancelNewEmail: function(){ 
    $("#my-modal").modal("hide"); 
    } 
}) 

inbox.handlebars

<div id="inbox-container"> 
    <!-- 
    YOUR INBOX CONTENT 
    The modal declared below wont show up unless invoked 
    --> 
    <a {{action addNewEmail}}>New Email</a> 
    <a {{action cancelNewEmail}}>Cancel</a> 
    <div class="modal hide fade in" id="my-modal"> 
    <!-- 
     Put your modal content 
    --> 
    </div> 
</div> 

esta manera:

  • El modal se mostrará en el botón haga clic
  • vista detrás no desaparece
  • El modal se ocultará al cancelar el botón
+0

Estaba asumiendo que quería que estuviera separado de la vista de la bandeja de entrada en realidad ... en cuyo caso probablemente debería haber una 'App.InboxModalView' con una devolución de llamada' didInsertElement' como esa. (También puede necesitar un 'willDestroyElement' para ocultarlo). Finalmente, una ruta' inboxModal' para conectarlo, * dentro * de la ruta 'inbox'. (Creo que podría ser un 'Ember.State' si no quiere una ruta per se.) – dechov

+0

Se olvidó de mencionar: necesitaría una salida dentro de la vista de la bandeja de entrada, para colocar el modal en. – dechov

+0

Sí, quería darle la idea de la implementación ... y deberíamos ocultarlo en willDestroyElement, el uso de outlet es opcional, supongo, ya que es un modal que viene en la parte superior de todo, pero si necesita una url para el modal, entonces deberíamos usar outlet, –

5

que tienen puesto en el uso de los verbos modales Twitter Bootstrap con Ember.js si alguien quiere más referencia:

http://generali.st/en/site/topics/show/82-modal-forms-in-emberjs

incluye un JSBin de trabajo para la fuente completa. También tiene algunas estrategias para DRYing up forms. OMI, el nombramiento de las cosas es un poco más convencional también.

4

Pasé un tiempo diseccionando Discurso para aprender cómo lo están haciendo. Básicamente tienen un modal único y el enrutador maneja los eventos para mostrar y ocultar el modal.

Estas son las cosas interesantes:

discurso/app/activos/javascripts/discurso/rutas/discourse_route.js

showModal: function(router, name, model) { 
    router.controllerFor('modal').set('modalClass', null); 
    router.render(name, {into: 'modal', outlet: 'modalBody'}); 
    var controller = router.controllerFor(name); 
    if (controller) { 
     if (model) { 
     controller.set('model', model); 
     } 
     controller.set('flashMessage', null); 
    } 
    } 

discurso/app/activos/javascript/discurso/rutas/application_route. js

events: { 
    editCategory: function(category) { 
     Discourse.Route.showModal(router, 'editCategory', category); 
     router.controllerFor('editCategory').set('selectedTab', 'general'); 
    } 

discurso/app/activos/javascript/discurso/views/modal/modal_body_view.js

Discourse.ModalBodyView = Discourse.View.extend({ 

    // Focus on first element 
    didInsertElement: function() { 
    $('#discourse-modal').modal('show'); 

    var controller = this.get('controller'); 
    $('#discourse-modal').on('hide.discourse', function() { 
     controller.send('closeModal'); 
    }); 

    $('#modal-alert').hide(); 

    var modalBodyView = this; 
    Em.run.schedule('afterRender', function() { 
     modalBodyView.$('input:first').focus(); 
    }); 

    var title = this.get('title'); 
    if (title) { 
     this.set('controller.controllers.modal.title', title); 
    } 
    }, 

    willDestroyElement: function() { 
    $('#discourse-modal').off('hide.discourse'); 
    } 

}); 

discurso/app/activos/javascripts/discurso/mixins/modal_functionality.js

Discourse.ModalFunctionality = Em.Mixin.create({ 
    needs: ['modal'], 

    /** 
    Flash a message at the top of the modal 

    @method blank 
    @param {String} name the name of the property we want to check 
    @return {Boolean} 
    **/ 
    flash: function(message, messageClass) { 
    this.set('flashMessage', Em.Object.create({ 
     message: message, 
     messageClass: messageClass 
    })); 
    } 

}); 

app/activos/javascripts/discurso/templates/modal/modal.js.handlebars

<div class="modal-header"> 
    <a class="close" {{action closeModal}}><i class='icon-remove icon'></i></a> 
    <h3>{{title}}</h3> 
</div> 
<div id='modal-alert'></div> 

{{outlet modalBody}} 

{{#each errors}} 
    <div class="alert alert-error"> 
    <button class="close" data-dismiss="alert">×</button> 
    {{this}} 
    </div> 
{{/each}} 

Y en sus application.js.handlebars: {{render modal}}