问题
DEBUG: Ember.VERSION : 1.0.0-rc.6 ember.js
DEBUG: Handlebars.VERSION : 1.0.0-rc.4 ember.js
DEBUG: jQuery.VERSION : 1.9.1
The controller is an Ember.ArrayContoller
& the content is loaded via the DS.RESTAdapter
.
This is the code I think I want, but it is never executed. I want to add an observer to controller.content
for the isLoaded
event.
App.ThumbnailScrollerView = Ember.View.extend({
tagName: "div",
didInsertElement: function() {
return this.get("controller.content").addObserver("isLoaded", function() {
return $(".jThumbnailScroller").thumbnailScroller();
});
}
});
This code is executed, but once for each object, I really only want it for the last object. controller.content.@each
App.ThumbnailScrollerView = Ember.View.extend({
tagName: "div",
didInsertElement: function() {
return this.get("controller.content.@each").addObserver("isLoaded", function() {
return $(".jThumbnailScroller").thumbnailScroller();
});
}
});
This is also never executed. controller.content.lastObject
App.ThumbnailScrollerView = Ember.View.extend({
tagName: "div",
didInsertElement: function() {
return this.get("controller.content.lastObject").addObserver("isLoaded", function() {
return $(".jThumbnailScroller").thumbnailScroller();
});
}
});
回答1:
I believe controller.content
is a ManyArray and ManyArrays do not implement isLoaded. They do have an isUpdating property.
Template:
{{#if content.isUpdating}}
LOADING...
{{else}}
{{view App.ThumbnailScrollerView}}
{{/if}}
App.ThumbnailScrollerView:
setupThumbnailScroller: function() {
this.$('.jThumbnailScroller').thumbnailScroller();
}.on('didInsertElement')
回答2:
Since you are using the RESTAdapter
by the time Ember gets to the view/template it's already too late to observe isLoaded
. This is by design and a key idea behind the Async router in RC.6.
Using the RESTAdapter
will result in a promise being return in your model
hook when you fetch data from the server. The workflow of the router is something like,
model
hook looks up data viaMyModel.find
etc, and returns a promise.- The async router pauses when it sees the promise and waits for the fetch to be completed.
- Then the router calles
setupController
and wires up the data returned to the controller. - Finally the
renderTemplate
is called to render the template with this data.
So by the time the view renders, the data has finished loading. The @each
is for a computed property that iterates over the content, and isn't relevant here.
Now, If my understanding of the question is correct. You have some content that loads via the model hook, and writes out the DOM that the thumbnail scroller
expects in your corresponding template.
After these images have finished loading you want to call the thumnailScroller()
on the target div, which would initialize this plugin.
ie:- You want to hook into an event when all images have loaded, and not when the data backing the content is loaded.
Ember doesn't provide any such events for image load. You will need to use an external library like imagesLoaded to do this.
imagesLoaded
provides callbacks for events like always
and done
to watch for such image completion events. Your didInsertElement
method for this would be,
didInsertElement: function() {
var _this = this;
var loader = imagesLoaded('.jThumbnailScroller');
loader.on('always', function() {
_this.$('.loader').hide();
_this.$('.jThumbnailScroller').thumbnailScroller();
});
loader.on('progress', function(loader, image) {
_this.set('nowLoading', image.img.src);
});
}
Here's a jsbin example. It uses jQuery promises with the Flickr API, but the same principles apply with ember-data's RESTAdapter
.
来源:https://stackoverflow.com/questions/17851533/initialize-a-jquery-plugin-when-the-content-for-an-ember-view-has-loaded