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 - 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.
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.