lundi 26 janvier 2015

ClassBinding not working in emberjs as property is not checked

A bit of background first, I'm building an event listing system, I want to use the same template to list the events wherever they appear, that can be from a search or as widgets on a page showing things like "happening shortly" events etc.


So, on a search the template is rendered as such



{{#each event in controller}}
{{render 'event-item' event}}
{{/each}}


This let's me use this template



<div class="event" {{action 'showModal' this}}>
{{#link-to 'details' this.id classNames="event__image" action="showModal" actionParam=this}}
<img src="{{unbound this.EventLogoURL}}" />
{{/link-to}}

{{console-log this}}
{{unbound AttractionName}}

<h4 class="event__title">
{{#link-to 'details' this.id action="showModal" actionParam=this}}
{{unbound this.EventName}}
{{/link-to}}
</h4>

<div class="event__info-links">
<span class="event__more-info">{{#link-to 'details' this.id action="showModal" actionParam=this}}More Info{{/link-to}}</span> <span class="event__separator">|</span> <span class="event__book-now">{{#link-to 'details' this.id action="showModal" actionParam=this}}Book Now{{/link-to}}</span>
</div>

<button {{action 'toggleWishlist' this bubbles=false}} {{bind-attr class="isInWishlist:icon-star2:icon-star :add-to-wishlist"}}>
{{#if isInWishlist}}
Remove from wishlist
{{else}}
Add to wishlist
{{/if}}
</button>
</div>


I have an item controller for the event which is



import Ember from 'ember';

export default Ember.ObjectController.extend({
needs: ['event/wishlist'],

isInWishlist: function(){
return this.get('controllers.event/wishlist').isInList(this.get('model'));
}.property('controllers.event/wishlist.[]')

});


On the search page this all works as expected, specifically isInWishlist works, now, when I want to use the event-item template as a widget I have created an event-suggestions controller and view, this is rendered on a page like so



{{render 'event-suggestions' events type='startingToday'}}


This then doesn't render correctly, as the context is different, so I had to make another template and change this to view.content to output the correct details, so the template I use when rendered this way is



<div class="event" {{action 'showModal' view.content}}>
{{#link-to 'details' view.content.id classNames="event__image" action="showModal" actionParam=view.content}}
<img src="{{unbound view.content.EventLogoURL}}" />
{{/link-to}}

{{unbound view.content.AttractionName}}

<h4 class="event__title">
{{#link-to 'details' view.content.id action="showModal" actionParam=view.content}}
{{unbound view.content.EventName}}
{{/link-to}}
</h4>

{{!-- From: &pound;{{unbound view.content.PriceFrom}} --}}

<div class="event__info-links">
<span class="event__more-info">{{#link-to 'details' view.content.id action="showModal" actionParam=view.content}}More Info{{/link-to}}</span> <span class="event__separator">|</span> <span class="event__book-now">{{#link-to 'details' view.content.id action="showModal" actionParam=view.content}}Book Now{{/link-to}}</span>
</div>

<button {{action 'toggleWishlist' view.content bubbles=false}} {{bind-attr class="isInWishlist:icon-star2:icon-star :add-to-wishlist"}}>
{{#if isInWishlist}}
Remove from wishlist
{{else}}
Add to wishlist
{{/if}}
</button>
</div>


Everything here works except for the isInWishlist (I can toggle it in and out of the wishlist that's fine) but the function never runs in the controller.


This is the CollectionView that is being rendered



import Ember from 'ember';

export default Ember.CollectionView.extend({
classNames: ['slider'],
parameters: {
'DateFrom': moment().format('DD/MM/YYYY'),
'DateTo': moment().format('DD/MM/YYYY'),
'TimeFrom': '10:00',
'TimeTo': '19:00',
'Latitude': BoxofficeENV.APP.defaultLatitude, // this.get('latitude'),
'Longitude': BoxofficeENV.APP.defaultLongitude, // this.get('longitude'),
'SortOrderID': 1,
'SortDirection': 0,
'Pagesize': 18,
'Pageno': 1,
'DistinctAttractions': 1
},

content: null,
type: null,

contentBinding: 'controller',

itemViewClass: 'event-suggestion-item',

emptyView: Ember.View.extend({
templateName: 'loading'
}),

didInsertElement: function() {
console.log('suggestion area inserted');
},

setupParameters: function(){
var type = this.get('type'),
property = this.get('property'),
params = this.parameters
;

// this is needed so we can cancel the request if it is made again before it finishes
params.UID = type;

this.send('prepareParams', params, type);
this.get('controller').send('getEvents', params, type);

}.on('didInsertElement'),

updateOnLocationChange: function() {

var type = this.get('type'),
property = this.get('property'),
params = this.parameters
;

if (type === 'closeToYou') {
// this is needed so we can canel the request if it is made again before it finishes
params.UID = type;

if(
this.get('controller').get('location').latitude !== BoxofficeENV.APP.defaultLatitude &&
this.get('controller').get('location').longitude !== BoxofficeENV.APP.defaultLongitude
) {
params.Latitude = this.get('controller').get('location').latitude;
params.Longitude = this.get('controller').get('location').longitude;

this.get('controller').send('getEvents', params, type);
}
}
}.observes('controller.location'),


actions: {
prepareParams: function(params, type){
switch(type) {
case 'startingShortly':
var dateTimeFrom = moment();
var dateTimeTo = moment();

dateTimeTo.add(7, 'day');

params.TimeFrom = '00:00';
params.TimeTo = '23:59';
params.DateFrom = dateTimeFrom.format('DD/MM/YYYY');
params.DateTo = dateTimeTo.format('DD/MM/YYYY');
params.MaxDistanceMiles = 10;
params.SortOrderID = 5;

params.Latitude = BoxofficeENV.APP.defaultLatitude;
params.Longitude = BoxofficeENV.APP.defaultLongitude;
break;

case 'closeToYou':
params.TimeFrom = '00:00';
params.TimeTo = '23:59';
params.MaxDistanceMiles = 50;

if(
this.get('controller').get('location').latitude !== BoxofficeENV.APP.defaultLatitude &&
this.get('controller').get('location').longitude !== BoxofficeENV.APP.defaultLongitude
) {
params.Latitude = this.get('controller').get('location').latitude;
params.Longitude = this.get('controller').get('location').longitude;
}
break;

case 'startingToday':
params.TimeFrom = moment().format('HH:mm');

var dateTime = moment().add(7, 'day');
params.TimeTo = dateTime.format('HH:mm');
params.DateTo = dateTime.format('DD/MM/YYYY');

params.SortOrderID = 6;
params.MaxDistanceMiles = 50;
break;
}
}
}


});


This is the array controller



import Ember from 'ember';

export default Ember.ArrayController.extend({
needs: ['application', 'event/wishlist'],

itemController: 'event-item',

location: function() {
return this.get('controllers.application').get('location');
}.property('controllers.application.location'),

actions: {
getEvents: function(params, property){
var self = this;
if (typeof this.store.adapterFor('event').xhrs[property] !== 'undefined'){
this.store.adapterFor('event').xhrs[property].abort();
}

this.store.findQuery('event', params).then(function(data){
self.set('model', data);

Ember.run.scheduleOnce('afterRender', this, function(){
Ember.$('.'+property).find('.iosslider').iosSlider({
desktopClickDrag: true,
snapToChildren: true,
frictionCoefficient: 0.97
});
});
});
}
}
});


and the two view files for event-item


event-item.js



import Ember from 'ember';

export default Ember.View.extend({
tagName: 'li',

classNames: ['fadeInUp','animated','event-collection__event'],

templateName: 'views/event-item'

});


event-suggestion-item.js



import Ember from 'ember';

export default Ember.View.extend({
tagName: 'div',

classNames: ['slide'],

templateName: 'views/event-suggestion-item'
});


Let me know if I need to be more specific.


I don't have time today to setup a jsfiddle example, but I'll see if I can setup one tomorrow if it'll help.





Aucun commentaire:

Enregistrer un commentaire