Not able to append html elements to el in backbone. - javascript

I seem to have a problem with the code below. I have a div element with the id='content' in my html. I wanted to replace 'body' element of el property with the div element but my hello world text doesn't when I typed el: $('div') or el:$('div#content') or el: $('#content'). I'm a beginner in backbone.js and in my understanding, I believe that this el property holds our parent tag where all our templates will be added as child elements(in this case 'body' tag being parent and 'p' tag being child).
(function($){
var ListView = Backbone.View.extend({
el: $('body'),
initialize: function(){
this.render();
},
render: function(){
(this.el).append("<p>Hello World</p>");
}
});
var listView = new ListView();
})(jQuery);

The View.el property should be defined as a jQuery selector (string), not a reference to HTML element.
From Backbone documentation:
var BodyView = Backbone.View.extend({
el: 'body'
});
Or as you wished,
el:'div#content'
When the view initializes, Backbone references the element in makes it available via the view.$elproperty, which is a cached jQuery object.
this.$el.append("<p>Hello World</p>");
The sample code you posted works, because there is always only one bodyelement, and that element already exists in the DOM when your view is rendered. So when you declare el:$('body'), you get a reference to the body element. The code in renderin works, because this.el is now a direct reference to the jQuery object:
(this.el).append("<p>Hello World</p>");
If you need to initialize a Backbone view using an existing DOM element (not a selector), Backbone documentation recommends passing it in the initialize function.

Related

Append view without container - backbone [duplicate]

I do an extensive use of templates, and I like to use full contained templates. I mean that I want to see in the template code all the DOM elements including the root one, like this:
<script type="text/template" id="template-card">
<div class="card box" id="card-<%= id %>">
<h2><%= title %></h2>
<div><%= name %></div>
</div>
</script>
But what Backbone likes is having a template like this:
<script type="text/template" id="template-card">
<h2><%= title %></h2>
<div><%= name %></div>
</script>
And defining the root element and its attributes in the JS code. What I think is ugly and confusing.
So, any good way to avoiding my Backbone View to wrapper my template with an extra DOM element?
I have been checking this issue thread: https://github.com/documentcloud/backbone/issues/546 and I understand there is not any official way to do it.. but maybe you can recommend me a non official way.
You can take advantage of view.setElement to render a complete template and use it as the view element.
setElement view.setElement(element)
If you'd like to apply a Backbone view to a different DOM element, use setElement, which will
also create the cached $el reference and move the view's delegated
events from the old element to the new one
Two points you have to account for:
setElement calls undelegateEvents, taking care of the view events, but be careful to remove all other events you might have set yourself.
setElement doesn't inject the element into the DOM, you have to handle that yourself.
That said, your view could look like this
var FullTemplateView = Backbone.View.extend({
render: function () {
var html, $oldel = this.$el, $newel;
html = /**however you build your html : by a template, hardcoded, ... **/;
$newel = $(html);
// rebind and replace the element in the view
this.setElement($newel);
// reinject the element in the DOM
$oldel.replaceWith($newel);
return this;
}
});
And a working example to play with http://jsfiddle.net/gNBLV/7/
Now you can also define a view's tagName as a function and create a class like this:
var MyView = Backbone.View.extend({
template: '#my-template',
tagName: function() {
// inspect the template to retrieve the tag name
},
render: function() {
// render the template and append its contents to the current element
}
});
Here's a working example
Backbone.Decarative.Views provides you with an alternative way to do this, without having to rely on setElement. For more, check out my answer here.

JQuery Selector not Selecting List Items in EmberJS View

I am creating an unordered list in an Ember.js view by using the each helper. I also have some Javascript that runs on the didInsertElement hook, which selects each list item. However, that selector fails to select any elements if I generate the list using the each helper. Any thoughts on how to get results from the selector?
relevant view:
<script type="text/x-handlebars" data-template-name="slider">
<ul>
{{#each slide in controller}}
<li><img src="./resource/locations/1/test.jpg"></li>
{{/each}}
</ul>
<br>
</script>
relevant JS:
App.SliderView = Ember.View.extend({
templateName: "slider",
didInsertElement: function() {
var self = this;
var items = $(">ul>li", self.$());
//...
}
});
Update:
I believe the problem arises because I am loading the models that populate my controller asynchronously. Is there any way to listen to the event that occurs when the model is first populated?
My Model Code:
App.Location = DS.Model.extend({
thenSlider: DS.hasMany("slide", {async: true})
});
App.Slide = DS.Model.extend({
//...
});
Looks good to me, you're probably facing a problem where your data is populating after didInsertElement has fired. didInsertElement only fires when Slider has been inserted initially, not necessarily when the elements inside of it are inserted/modified.
http://emberjs.jsbin.com/liluxece/1/edit
Since it's async, I'd use render and hook it up to another view, that way you can use didInsertElement on a case by case situation for each item.
{{render 'template' context}}
Here's an example
http://emberjs.jsbin.com/liluxece/5/edit

attach view to exists element with embjer.js

what's the implementation of attaching exist html element to Ember.js view without using any template engine. ?
for example in Backbone.js i should give the view the el property
In view you can do:
didInsertElement: function () {
var domNode = this.$().get(0);
$(domNode).append('//your html element goes');
}

jQuery - How to link together a DOM element and a Javascript object?

I want to be able to link a javascript object with a dom element but cant find a way for this to be done properly. An example: say when opening a page with an inventory it loads all the items contained in it and when I hover over the images inside it creates a small tooltip with some information. Well there will be much of these items on the page and i want to be able to link the DOM element with an object so i can access its properties easily. I hope im explaining my self properly.
say I had this inside an inventory:
<div id="slot1"><img id="item1"></div>
<div id="slot2"><img id="item2"></div>
and say i have a javascript object called slot1 and slot2:
the object slot1 has all the properties that need to be shown in the tooltip so i would like to do something like this in the mouseover event:
this.showTooltip()
any help would be great ty if i need to explain it better just say!
-Thaiscorpion
Use jQuery data:
$("div.hasToolTip").hover(
function() {
//Get the associated data with the DOM element
//with $(this).data(someKey)
showToolTip($(this).data('toolTipInformation'));
},
function() {
//Here you can hide all tooltips
}
);
Obviously, before you can register this event, you have to assign the object to every DOM element with $(selector).data(key, value).
These example expects that every DOM element which should have a tooltip has a class named .hasToolTip.
Look at the jQuery documentation for more information about the .data() function.
Just have the javascript object know the ID of the object it's watching.
function Tooltipper(divID) {
this.id = divID;
}
Tooltipper.prototype.showTooltip = function () {
// do tooltip stuff
$('#' + this.id).tooltip(); // assuming that it has a tooltip thing
};
var slot1 = new Tooltipper('slot1'),
slot2 = new Tooltipper('slot2');
And then:
slot1.showTooltip();
Or better yet, instead of passing in the ID, pass in the object:
var slot1 = new Tooltipper($('#slot1'));
This way you don't have to do a DOM lookup each time.

MooTools: Element disposal

Let's say I have two elements on a page. One is a div, and the other is its child, an achor. Let's say that I've added an event to that anchor via anchor.addEvent('click', ...). If I set the div's .innerHTML = '', does the 'click' event associated with the anchor get removed/disposed of/garbage collected?
It depends if you have still reference to "anchor" DOM instance. If so, it will stay in memory until all references are removed.
Test example:
var parent = new Element('div');
var child = new Element('div', {
events : {
click : function() {
alert('child clicked');
}
}
});
child.innerHTML = 'child content';
parent.appendChild(child);
document.body.appendChild(parent);
parent.innerHTML = 'parent content';
document.body.appendChild(child);
According to the MooTools API: destroy() is a method that:
Empties an Element of all its children, removes and garbages the Element. Useful to clear memory before the pageUnload.
I suspect that what happens to anchors removed when their parent elements are removed using innerHTML = '' is going to depend on the browser.
jQuery offers an empty() method, I am guessing other libraries probably offer methods too. You can see a pretty good discussion of this topic in Removing an element from DOM.
IMHO, you should use empty() instead of innerHTML = "".
The reference will remain like #nemisj said, but it will be "floating" and useless.
I did some tests here: test case, maybe you'll find interesting.

Categories

Resources