Bootstrap Popovers with ember.js template

后端 未结 5 1864
礼貌的吻别
礼貌的吻别 2021-02-06 08:44

I\'m trying to use Bootstrap Popover with EmberJS, so that the content of the popover will be a ember/handlebars template (with binding etc). How can this be done? (Ember 1.0.0-

相关标签:
5条回答
  • 2021-02-06 09:26

    Here is a working example for an ember bootstrap popover (see http://jsfiddle.net/72fSd/):

    App.Popover = Ember.View.extend({
            parentSelector: '',
            contentSelector: '',
            didInsertElement: function () {
                var self = this;
                $(self.parentSelector).popover({
                    html: true,
                    content: function() {
                        var $content = $(self.contentSelector);
                        return $content.html();
                    }
                });
            }
    

    Instantiate the view:

    {{view App.Popover templateName="my-popover-content" parentSelector=".popoverButton" contentSelector="#popovercontent"}}
    

    Here, parentSelector might e.g. select a button. Make sure you have a div container with id #popovercontent in your my-popover-content template in order for the contentSelector to work. Of course you need to load the template prior to initialization of the view.

    Two-way binding should work with that solution.

    0 讨论(0)
  • 2021-02-06 09:26

    ex if you want to popup a image do something like this in you view

    imgTag: '<img src="smiley.gif" alt="Smiley face" height="42" width="42">',
    
    didInsertElement: function () {
        var self = this;
        Ember.run.schedule('actions', this, function () {
            self.$().popover({
                title: 'Smile!!!',
                html: true,
                content: self.get('imgTag'),
                placement: 'bottom',
                trigger: 'hover'
            });
        });
    },
    
    willDestroyElement: function () {
        this.$().popover('destroy');
    }
    
    0 讨论(0)
  • 2021-02-06 09:34

    I took Terry's answer a bit further and think I've come up with a simple, general solution to this problem.

    I created a bootstrap-popover component like so:

    App.BootstrapPopoverComponent = Ember.Component.extend({
      tagName: 'div',      //whatever default you want... div is default anyway here
      classNames: '',      //whatever default you want
      placement: 'bottom', //whatever default you want
      didInsertElement: function () {
        var component = this,
            contents = this.$('.popoverJs');
        component.$().popover({
          animation: false,
          placement: component.get('placement'),
          html: true,
          content: contents
        }).on('show.bs.popover', function () {
          contents.removeClass('hide');
        });
      },
      willDestroyElement: function () {
        this.$().popover('destroy');
      }
    });
    

    Here is the associated template:

    <script type="text/x-handlebars" id="components/bootstrap-popover">
      {{title}}
      <div class="popoverJs hide">
        {{yield}}
      </div>
    </script>
    

    Note the use of the "hide" class to hide the yielded contents initially. This class is simply "display: none". Without this, things won't work quite how you'd hope.

    Once you have that, you can do simply do something like this whenever you want a popover:

      {{#bootstrap-popover title="My Fancy Popover" tagName="button"}}
        <ul>
          <li>my</li>
          <li>awesome</li>
          <li>popover</li>
          <li>contents</li>
          <li>example</li>
        </ul>
      {{/bootstrap-popover}}
    

    The contents should be able to be whatever you want -- any arbitrary HTML, rendering a component or partial, etc.. Naturally, you can specify other tagNames, classNames, title, placement, etc. as you see fit.

    I hope this solution helps.

    0 讨论(0)
  • 2021-02-06 09:40

    I took Robert's answer above a bit further. I created a Component and also just use the jQuery element for the content instead of calling .html(). (This alleviates the problem of having duplicated IDs in the page.)

    App.CustomPopoverComponent = Ember.Component.extend({
      tagName: 'button',
      classNames: 'btn btn-default',
      type: 'button',
      popoverContentSelector: '',
      didInsertElement: function () {
        var component = this,
            contents = $(component.get('popoverContentSelector'));
    
        component.$().popover({
          placement: 'bottom',
          html: true,
          content: contents
        }).on('show.bs.popover', function () {
          contents.removeClass('hide');
        });
      },
      willDestroyElement: function () {
        this.$().popover('destroy');
      }
    });
    

    I used Bootstrap's 'hide' class to hide the contents initially. Then I removed the 'hide' class the first time to the popover is shown. From then on things work as expected.

    This is how to use the component in your handlebars template:

      {{#custom-popover popoverContentSelector='.popoverContents'}}
        Popover Button
      {{/custom-popover}}
    
    0 讨论(0)
  • 2021-02-06 09:46

    I ran into this problem as well and had the same problem Robert mentioned above where the acceptable solution simply doesn't scale well to more complicated scenarios.

    I ran into a very elegant fix, but I'm not sure how future-friendly it is. I'm taking advantage of the function renderToBuffer - see below:

    //make your popover view to be created later
    App.PopoverView = Ember.View.extend({
      templateName : 'name-of-your-template-with-content'
    });
    
    //then you make your link that will trigger the popover
    App.PopoverLinkView = Ember.View.extend({
    
      tagName : 'a',
    
      didInsertElement : function(){
    
      var that = this;
    
      this.$().popover({
        'html' : true,
        'content' : function(el){
        var detailView = App.PopoverView.create();
        var html = detailView.renderToBuffer().buffer;
        return html;
        }
      });
    
      }
    
    });
    

    The advantage here is that you can pass in a model and make things dynamic. Haven't tested it thoroughly, but wanted to get this out there to potentially help others.

    0 讨论(0)
提交回复
热议问题