Initialize a jQuery plugin when the content for an Ember.View has loaded

房东的猫 提交于 2019-12-08 21:00:34

问题


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,

  1. model hook looks up data via MyModel.find etc, and returns a promise.
  2. The async router pauses when it sees the promise and waits for the fetch to be completed.
  3. Then the router calles setupController and wires up the data returned to the controller.
  4. 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

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