【问题标题】:modal popup with ember 1.0 rc6带有 ember 1.0 rc6 的模态弹出窗口
【发布时间】:2013-07-01 03:18:20
【问题描述】:

如何使用最新版本的 ember.js 创建模态弹出窗口?我发现的每个示例都使用了前一段时间已弃用的 connectOutlet,而且我是 ember 的新手这一事实也无济于事。

我的应用程序模板中已经有一个命名的插座,但是如何将我的模态弹出视图从控制器事件呈现到此插座?还是应该使用路由事件?

【问题讨论】:

  • 你看过这篇文章了吗? discuss.emberjs.com/t/…
  • 是的,但我不认为那里的解决方案很好,有人从控制器访问 DOM 以显示模式。 presentacion 中有一个非常好的例子,但不幸的是它使用了 connectOutlets,我无法让它工作。

标签: ember.js modal-dialog


【解决方案1】:

亚当霍金斯刚刚发表了一篇关于这个主题的优秀文章,你可以在这里找到它:http://hawkins.io/2013/06/ember-and-bootstrap-modals/

总结一下:

  • 在 application.hbs 中包含 {{outlet modal}}
  • 使用事件从路由器渲染到插座
  • 由视图的 didInsertElement 钩子触发的动画以及它的 close 动作
  • Modal 的 close 动作应该以视图为目标,该视图会等待动画完成,然后再将 close 事件发送到路由器

来自亚当的 jsfiddle:

App.ApplicationRoute = Ember.Route.extend({
  events: {
    open: function() {
      this.render('modal', { into: 'application', outlet: 'modal' });
    },

    close: function() {
      this.render('nothing', { into: 'application', outlet: 'modal' });
    },

    save: function() {
      alert('actions work like normal!');
    }
  }
});

App.ModalView = Ember.View.extend({  
  didInsertElement: function() {
    this.$('.modal, .modal-backdrop').addClass('in');
  },

  layoutName: 'modal_layout',

  close: function() {
    var view = this;
    // use one of: transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd
    // events so the handler is only fired once in your browser
    this.$('.modal').one("transitionend", function(ev) {
      view.controller.send('close');
    });

    this.$('.modal, .modal-backdrop').removeClass('in');
  }
});

【讨论】:

【解决方案2】:

当使用 Bootstrap 3.0 和最终的 Ember 1.0 时,我无法让这段代码工作。 我重写了一下(在coffeescript中,布局和模板把手已经用Grunt的emberTemplates预编译为js)

app.coffee

App.ApplicationRoute = Ember.Route.extend({

    actions: 
        open: ->
            console.debug('open action triggered')
            @render('ContactModal', {into: 'profile', outlet: 'contactModal'})

        close: ->
            @render('nothing', {into: 'profile', outlet: 'contactModal'})

        save: ->
            alert('Send the message to person')
})

modal_view.coffee

App.ModalView = Ember.View.extend({
didInsertElement: ->
    @$('.modal').modal('show')
    view = @
    @$('.modal').on("hidden.bs.modal", (ev)->
        view.controller.send('close')
        return
    )

layout: Ember.TEMPLATES['modal_layout']

template: Ember.TEMPLATES['modal']

actions:
    close: ->
        @$('.modal').modal('hide')
        return
})

这种方式在模态外部单击也可以正确关闭它,因为从出口中删除模板是在隐藏模态时完成的。

modal.handlebars:

<div class="modal-dialog">
<div class="modal-content">
  <div class="modal-header">
    <button type="button" class="close" {{action close target="view"}}>&times;</button>
    <h3 class="modal-title">Contact</h3>
  </div>
  <div class="modal-body">
    <p>Here will go the contact form and contact template picker</p>
  </div>
  <div class="modal-footer">
    <a href="#" class="btn btn-default" {{action close target="view"}}>Close</a>
    <a href="#" class="btn btn-primary" {{action save}}>Send</a>
  </div>
</div>

modal_layout.handlebars

<div class="modal fade" role="dialog">{{yield}}<div>

我还放了一个 jsfiddle:http://jsfiddle.net/bG4F8/5/ 玩得开心:)

【讨论】:

    【解决方案3】:

    感谢您分享您的代码 Mike & Damian!这是我的使用方法:

    路由器:

    App.Router.map ()->
      @resource 'posts', ->
        @resource 'post', path:':post_id', ->
          @route 'modal'
    

    路线:

    App.PostModalRoute = Em.Route.extend
      setupController: (model, controller) ->
        @controllerFor('post.modal').set 'content', @modelFor('post')
        @render 'posts/modal', into: 'application', outlet: 'modal'
        # Note: you need outlet named 'modal' in application template
    

    查看:

    App.ModalView = Ember.View.extend
      didInsertElement: ->
        @$('.modal').modal('show').on 'hidden.bs.modal', =>
          @get('controller').send 'close'
    
      layout: Ember.Handlebars.compile '<div class="modal hide fade">{{yield}}</div>'
    

    模板:

    App.ModalView
      .modal-header
        button type="button" class="close" data-dismiss="modal" aria-hidden="true" ×
        h3
          | Post #
          = id
      .modal-body
        ...
    

    【讨论】:

      【解决方案4】:

      使用组件,并依靠 Bootstrap 自己的解除功能来触发sendActionwillDestroyElement 负责拆毁东西。它在 CoffeeScript 和 Emblem.js 中,因为我从我的代码中提取了这个:

      application.coffee:

        ApplicationRoute = Ember.Route.extend
          actions:
            openModal: (modalName) ->
              @render modalName,
                into: "application"
                outlet: "modal"
      
            closeModal: ->
              @disconnectOutlet
                outlet: "modal"
                parentView: "application"
      

      modal-dialog.coffee:

        ModalDialogComponent = Ember.Component.extend
      
          didInsertElement: ->
            @$(".modal").modal "show"
            @$(".modal").on "hidden.bs.modal", => @sendAction()
      
          willDestroyElement: ->
            @$(".modal").modal "hide"
            @$(".modal").off()
      

      模态对话框.embl:

      .modal.fade
        .modal-dialog
          .modal-content
            .modal-header
              button.close type="button" data-dismiss="modal"
                span aria-hidden="true" &times;
                span.sr-only Close
              h4.modal-title Modal title
            .modal-body
              = yield
            .modal-footer
              button.btn.btn-default type="button" data-dismiss="modal" Close
              button.btn.btn-primary type="button" Save
      

      modal.embl:

      = modal-dialog action="closeModal"
        p Hello
      

      【讨论】:

        【解决方案5】:

        如果您正在寻找更直观、更简单的问题解决方案,我强烈建议您观看 Brett Valentine 的这个 youtube 视频。

        Binding to Twitter Bootstrap with Ember

        我在当地的 emberjs 聚会上遇到了开发人员,但他介绍了将引导模式作为组件集成到项目中。

        将引导元素集成为可重用组件是有意义的,因为您将来可能会在其他项目中使用它们。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-09-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多