问题
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