Emberjs - Ember conditionals break Jquery. Need simple fix - javascript

Handlebar conditionals actually delete the DOM elements inside of the conditionals, JQuery thinks that the newly generated DOM elements, despite their matching ID or class is something entirely different.
I need a simple solution for this. A solution that I can wrap my solutions in once per page. I don't want to have to tack .observes() after everything as that seems like a shoddy work-around
Right now I put my Jquery in the didInsertElement{} in my current view that is being used.
Simple Example:
exampleView -
didInsertElement {
$('#exampleButton').on('click', function() {
console.log('To Ember. Or to Angular. That is the question.')
}
}
example.hbs -
{{#if booleanTrue}}
<button id="exampleButton">Button go!</button>
{{/if}}

That approach is not best for Ember. For the future release of Ember they are planing to remove jQuery dependency. With Ember you don't have to use jQuery.
rewrite your code like this:
didInsertElement: function(){
this.$().hide().fadeIn('slow'); // or any animation that you want
},
actions: {
myButtonAction: function(){
//do something
}
}
{{#if booleanTrue}}
<button id="exampleButton" {{action "myButtonAction"}}>Button go!</button>
{{/if}}
willDestroyElement is not right hook for animation. So you have to trigger it yourself.
I use my custom action like
actions: {
deleteClicked: function(){
var self = this;
this.$().animate({ height: 'toggle' }, 300, function() {
self.set('booleanTrue', false);
});
}
}
due to your comment I changed my answer

Related

Is there any Ember event similar to `onload`

I want to execute JavaScript when all content (e.g. images) has been loaded in my Ember application.
I already tried using didInsertElement() and didRender() hooks, but it looks like they do not wait for background images to load.
Here's what my component's code snippet looks like:
export default Ember.Component.extend({
didInsertElement() {
this._super(...arguments);
Ember.run.scheduleOnce('afterRender', this, function() {
var home =$('#main-outlet')[0];
home.className += " homePage";
startTimer(5);
});
},
});
Any solution or an alternative approach for this?
Ember does not have an event that is equivalent to onload.
However, regarding an alternate approach, you could leverage Ember’s alias for jQuery, in combination with the didInsertElement hook within your component, to achieve the order of execution that you are looking for. Try this:
export default Ember.Component.extend({
didInsertElement() {
Ember.$(window).on('load', this.executeCssAnimations);
},
executeCssAnimations() {
// your CSS and animation logic would go here
Ember.$('.big-background')
.text('NOW READY FOR CSS and ANIMATION UPDATES.')
.css('color', 'yellow');
},
willDestroyElement(...args) {
this._super(...args);
Ember.$(window).off('load', 'window', this.executeCssAnimations);
},
});
The willDestroyElement hook has been included as well, to show proper teardown and removal of the load event listener from window.
I’ve created an Ember Twiddle example to demonstrate this for you.

Use append in Backbone View Template

$el.find(".detail").append("<div class='noImageDetail'>teest</div>");
But not working. Checked in devtools, not found any bug. How can I use append in Backbone? Also, how can I use if - else?
You don't have any errors on your code as it is, now you need to make sure that exists something inside of your "el" with the "detail" class, example
HTML
<div id="book">
<div class="detail">Book:</div>
</div>
JS
var BookView = Backbone.View.extend({
el: '#book',
initialize: function() {
this.render();
},
render: function() {
this.$el.find(".detail").append("<div class='noImageDetail'>teest</div>");
}
});
var bookView = new BookView();
You need to use this.$el.find('selector') you could also use this.$('selector') which will save you some keystrokes since it's basically and alias to this.$el.find
I wrote an example in this plunker
The if - else is basic JavaScript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else

Ember and external js scripts

Ok, i'm a really newbie to Ember JS, but i'm having a play and working my way through things.
So far I'm really liking it, but…
I wanted to use something like: https://github.com/ed-lea/jquery-collagePlus, which created a masonry style layout.
I have create the route, and the navigation to that view, but… how do you apply the effect?
Normally a:
$(window).load(function () {
$('.Collage').collagePlus();
});
would do the job at the bottom of the page, but i'm guessing popping in a:
App.GridRoute = Ember.Route.extend({
afterModel: function(){
$('.Collage').collagePlus();
}
});
Might be better, but that's not working…
any help, pointers on this welcome, be gentle as i'm not understanding it quite yet!
PS. i'm also using bootstrap and bootstrap ember (probably doesn't matter…)
The place to do it it's the View, handling the didInsertElement event. I believe the View it's a good place to isolate any logic related to the DOM.
App.GridView = Ember.Route.extend({
classNames: ['Collage'],
didInsertElement: function(){
this.$().collagePlus();
}
});
A useful link:
Hope it helps!

Ember Collapsible Container

I'm using Ember.js with handlebars and I need to make a div within my page collapse/expand when clicked. I know how to do this in jQuery, but I can't use any jQuery. Does anyone know how to accomplish this? Also I don't want to just toggle a hide attribute, I need the full sliding up and down feature for collapsing. If anyone has any ideas, I'd really appreciate it.
Thanks
Clicking on your view will cause a click event to be triggered. You can code your animation in any manner you want inside a click event handler in your view:
CollapsableView = Ember.View.extend({
click : function(event) {
this.$().toggle('fast');
}
})
The proper way of doing this in Ember is via the awesome Liquid Fire addon.
The outline:
Install Liquid Fire into your project.
Define a transition like this:
this.transition(
this.hasClass('transition-spoiler'),
this.toValue(true),
this.use('toDown'),
this.reverse('toUp')
);
In your controller/component, create a property spoilerIsVisible and a toggleSpoiler property:
spoilerIsVisible: false,
actions: {
toggleSpoiler: function() {
this.toggleProperty('spoilerIsVisible');
}
}
In your page/component template, create a button and a spoiler wrapper like this:
<button {{action 'toggleSpoiler'}}>
{{if spoilerIsVisible 'Show spoiler' 'Hide spoiler'}}
</button>
{{#liquid-if spoilerIsVisible class="transition-spoiler"}}
<p>Dumbledore dies</p>
{{/liquid-if}}
Note that you can wrap steps 3-4 into an x-spoiler component or something.
I do something similar, but with a tree-structure. I have written a blog post about this previously here: http://haagen-software.no/blog/post/2012-05-05-Ember_tree
It has the features you need in it, in that it adds and removed elements from the DOM when the nodes are clicked on.
A working example can be seen in an app I am currently building here: https://github.com/joachimhs/EurekaJ/tree/netty-ember/EurekaJ.View/src/main/webapp

Can't get rid of the outer div of a backbone.js view

I'm using Backbone 0.9.2 and I have a mustache template that uses twitter bootstrap and looks something like this:
<div class="modal hide something" id="something-modal">
...
</div>
I tried getting rid of the extra <div> that backbone adds because I want the view to be 1-to-1 as my template. My render function looks something like:
render: function(){
var $content = $(this.template()),
existing_spots = $content.find('.spots-list'),
new_spot;
this.collection.each(function (spot) {
new_sweetspot = new SpotView({ model: spot });
existing_spots.append(new_spot.render().el);
});
$content.find("[rel=tooltip]").tooltip();
this.setElementsBindings($content);
//this.$el.html($content).unwrap('div'); // didn't work!
this.$el.html($content);
console.log(this.$el);
return this;
}
I know that by adding:
tagName: "div",
className: "modal",
I'll get rid of it, but I want the control of the view's elements to be of the template, not of the JS code.
this.SetElement will cause the list NOT to be updated (it'll be empty), this.$el = $content; won't work as well.
There was a good thread on this last week on SO.
Backbone, not "this.el" wrapping
tl;dr you can use setElement, but you really need to know when things happen in backbone to make sure everything is wired up correctly.

Categories

Resources