couldn't get Bootstrap carousel to work with Ember

♀尐吖头ヾ 提交于 2019-12-10 12:19:46

问题


trying to understand why its not working.

I have something like this.

<div class="carousel slide" id="new-prospect-container">
   <div class="carousel-inner">
   {{#each model}}
      <div class="item">
      ...
     </div>
   {{/each}}
   </div>
</div>

But Botostrap's first class api means that we don't need to execute any JS methods and their widgets will work automatically. The problem is I suspect Bootstrap would have executed this prior to my {{model}} being filled up by an Ajax requests. So this Carousel won't work.

What's annoying is i already tried turning off their data-api - $(document).off('.data-api'); and manually call their carousel method - still won't work.

The carousel works with hard coded data - but once I try to populate the carousel div items from my Ember model, it just stops working.

  1. Any idea?
  2. Why does this exist - https://github.com/emberjs-addons/ember-bootstrap ? does it exist to exactly solve my issue here? (although there's no carousel)

回答1:


1 - I hope that this jsfiddle solve your problem.

App.CarouselView = Ember.View.extend({    
    templateName: 'carousel',
    classNames: ['carousel', 'slide'],
    init: function() { 
        this._super.apply(this, arguments);
        // disable the data api from boostrap
        $(document).off('.data-api');      
        // at least one item must have the active class, so we set the first here, and the class will be added by class binding
        var obj = this.get('content.firstObject');
        Ember.set(obj, 'isActive', true);
    },
    previousSlide: function() {
        this.$().carousel('prev');
    },
    nextSlide: function() {
        this.$().carousel('next');
    },
    didInsertElement: function() {
        this.$().carousel();
    },
    indicatorsView: Ember.CollectionView.extend({
        tagName: 'ol',
        classNames: ['carousel-indicators'],        
        contentBinding: 'parentView.content',
        itemViewClass: Ember.View.extend({
            click: function() {
                var $elem = this.get("parentView.parentView").$();
                $elem.carousel(this.get("contentIndex"));
            },
            template: Ember.Handlebars.compile(''),
            classNameBindings: ['content.isActive:active']            
        })
    }),
    itemsView: Ember.CollectionView.extend({        
        classNames: ['carousel-inner'],
        contentBinding: 'parentView.content',
        itemViewClass: Ember.View.extend({
            classNames: ['item'],
            classNameBindings: ['content.isActive:active'],
            template: Ember.Handlebars.compile('\
                <img {{bindAttr src="view.content.image"}} alt=""/>\
                <div class="carousel-caption">\
                    <h4>{{view.content.title}}</h4>\
                    <p>{{view.content.content}}</p>\
                </div>')
        })
    })
});

2 - I don't know why the carousel isn't include in ember-boostrap.




回答2:


So I have a solution for this, but it's not for the squeamish.

Bootstrap isn't specific enough about what elements it looks for in the case of the Carousel. When the carousel function goes to inventory what elements it's to manipulate, it chokes on the metamorph tags that Ember injects into the DOM. Basically, when it goes to see how many images there are, it will always find 2 more than there actually are.

I made changes to the underlying code of the carousel in the bootstrap library, here's what I did.

Line 337, change:
this.$items  = this.$active.parent().children()
TO
this.$items  = this.$active.parent().children('.item')


Line 379, change:
var $next     = next || $active[type]()
TO
var $next     = next || $active[type]('.item')


Line 401, change:
var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
TO
var $nextIndicator = $(that.$indicators.children('li')[that.getActiveIndex()])

This helps the carousel plugin ignore the metamorph tags.

Hope this helps.




回答3:


I had the same issue and solved it by using the following method. Note that I'm using ember-cli but it's fairly easy to adapt.

This is the templates/components/photo-carousel.hbs file:

<div id="my-carousel" class="carousel slide" data-ride="carousel">

    <ol class="carousel-indicators">
        {{#each photo in photos}}
            <li data-target="#my-carousel" data-slide-to=""></li>
        {{/each}}
    </ol>

    <div class="carousel-inner" role="listbox">
        {{#each photo in photos}}
            <div class="item">
                <img {{bind-attr src="photo.completeUrl" title="photo.caption" alt="photo.caption"}} />
                <div class="carousel-caption">
                    {{photo.caption}}
                </div>
            </div>
        {{/each}}
    </div>

    <!-- removed right and left controls for clarity -->
</div>

This is the components/photo-carousel.js:

export default Ember.Component.extend({
    didInsertElement: function () {

        // Add the active classes (required by the carousel to work)
        Ember.$('.carousel-inner div.item').first().addClass('active');
        Ember.$('.carousel-indicators li').first().addClass('active');

        // Set the values of data-slide-to attributes
        Ember.$('.carousel-indicators li').each(function (index, li) {
            Ember.$(li).attr('data-slide-to', index);
        });

        // Start the carousel
        Ember.$('.carousel').carousel();
    }
});

Note that setting the active classes manually will not be required with future versions of Ember since the each helper will provide the index of the current item.



来源:https://stackoverflow.com/questions/18068993/couldnt-get-bootstrap-carousel-to-work-with-ember

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!