Applying JQuery effect when ember-data has finished loading and element is rendered

谁说胖子不能爱 提交于 2019-12-23 17:40:30

问题


I have a list of items that I want to make draggable. I am using ember-data to get the items from my API and then render them in a view with an ArrayController. I can successfully load the items and render them but I don't know where or when to put the JQuery draggable function.

I have tried using didInsertElement on my view but this is triggered when the view is rendered and not when the items are loaded. I have also tried to put an observer on my ArratController to run the code when the array length changes (i.e when an element is added to the array) None of these things worked.

Any ideas?

My JS code:

var REVISION = 9; 

// Application namespace
var App = Ember.Application.create({
    ApplicationView: Ember.View.extend({
        templateName:  'application',
        classNames: ['application-view']
    }),
    ApplicationController: Ember.Controller.extend(),
    RewardsView:  Em.View.extend({
        templateName:  'rewards',
        click: function(event) {
            console.log(event);
            //window.location.href = event
        },
        didInsertElement: function() {
            this.$(".draggable").draggable();
        }
    }),
    RewardsController:  Em.ArrayController.extend({
        rewardAdded: function() {
        $(".draggable").draggable({
            cursor: 'move',          // sets the cursor apperance
            revert: 'invalid',       // makes the item to return if it isn't placed into droppable
            revertDuration: 900,     // duration while the item returns to its place
        });
        }.observes('length')
    }),
    ready: function(){
        console.log("Created App namespace");
    },
    Router: Ember.Router.extend({
        goToRewards:  Ember.Route.transitionTo('root.rewards'),
        root:  Ember.Route.extend({
            index:  Ember.Route.extend({
                route:  '/',
            }),
            rewards:  Ember.Route.extend({
                route: '/rewards',
                enter: function ( router ){
                  console.log("The rewards sub-state was entered.");
                },
                connectOutlets:  function(router, context){
                  router.get('applicationController').connectOutlet('content','rewards', App.store.findAll(App.Rewards));
                }
            }),
        })
    })
});

App.Rewards = DS.Model.extend({
    provider: DS.attr('string'),
    name: DS.attr('string'),
    description: DS.attr('string'),
    discount: DS.attr('string'),
    img: DS.attr('string'),
    video: DS.attr('string'),
    price: DS.attr('string'),
    available_quantity: DS.attr('string'),

    didLoad: function() {
        console.log('model loaded', this);
    }
});

App.store = DS.Store.create({
    revision: REVISION,
    adapter: DS.DjangoTastypieAdapter.extend({
      serverDomain: "http://example.com",
      namespace: "api/v1"
    }),
});

// Start!
App.initialize();

My handlebars template:

{% handlebars "rewards" %}
<div class="row-fluid">
  <div class="span6">
    <div class="box paint color_7">
      <div class="title">
        <div class="row-fluid">
          <h4> Available Rewards </h4>
        </div>
      </div>

      <!-- End .title -->
      <div class="content">
        <div class="accordion" id="accordion2">
          {{#each reward in controller}}
            <div class="draggable accordion-group">
              {{#with reward}}
                {{#if isLoaded}}
                  <div class="accordion-heading"> 
                    <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#accordion2" {{bindAttr href="reward.id"}}> {{name}} {{id}} </a> 
                  </div>
                  <div {{bindAttr id="reward.id"}} class="accordion-body collapse" style="height: 0px; ">
                    <div class="accordion-inner"> {{description}} </div>
                  </div>
                {{else}}
                    Loading...
                {{/if}}
              {{/with}}
            </div>
          {{/each}}

        </div>
      </div>
      <!-- End .content --> 
    </div>
    <!-- End .box --> 
  </div>
{% endhandlebars%}

回答1:


use findQuery instead of findAll

router.get('applicationController').connectOutlet('content','rewards',App.store.findQuery(App.Rewards));

You get the property isLoaded for the content, now you can add observer on isLoaded property to run your required functionality as follows

startDraggableFunctionality: function(){
  if(this.get('content.isLoaded'){
    /*Your code goes here...*/
  }
}.observes('content.isLoaded')

After Rendering + Data loaded
Inside the view add the following method as follows

View 
//This method will be executed when the view has finished rendering
afterRender: function(){
  this.get('controller').set("viewRendered", true);
}
Controller 
viewRendered: false, //set it to false initially
startDraggableFunctionality: function(){
  if(this.get('content.isLoaded') && this.get('viewRendered')){
    /*Your code goes here...*/
  }
}.observes('content.isLoaded', 'viewRendered')

This way if the view renders before loading content, isLoaded make sures that function will be executed only after data has been loaded & vice-versa



来源:https://stackoverflow.com/questions/13788194/applying-jquery-effect-when-ember-data-has-finished-loading-and-element-is-rende

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