Passing parameters to a Backbone View (id, className and so on) - javascript

I have some code that makes a Backbone.View, based on some params I pass to it, like so:
// The Form View
var FormView = Backbone.View.extend({
initialize: function (opts) {
debugger; // This is here only to figure out what gets executed first: if "id" method or "initialize"
this.options = {};
this.options.id = opts.id;
this.options.className = opts.class;
},
id: function () {
debugger; // The application will stop here before the debugger I set in the initialize method
return this.options.id; // options is undefined!
},
className: function () {
return this.options.className; // options is undefined!
}
});
// The params
var params =
fid: "some-form",
class: "form-horizontal"
};
var myForm = new FormView(params);
But the this.options property is always undefined. As I can see, the method that sets the view's properties runs BEFORE the initialize method. As a workaround I think I could access the initialize method inside de id callback and call its arguments, but I'm not sure how to do this properly. And I don't think this is a good approach either.
Any ideas? - Thanks in advance.

Why don't you use the usual way of passing options to the view? Something like:
var FormView = Backbone.View.extend({
initialize: function () {
this.foo = this.options.foo;
this.bar = this.options.bar;
}
});
var params = {foo: '1', bar: '2'};
var v = new FormView(params);
You can also pass as params {id: '1', className: 'your-class'} and Backbone will apply it automatically to the respective id and className properties of the target View.

You don't seem to be initializing the options attribute properly. You should have
initialize: function (opts) {
this.options = {}; // you were missing this part
this.options.id = opts.id;
this.options.className = opts.class;
},

Related

Cannot access model property on class definition

I send value to model as attribute
Views.App = Backbone.View.extend({
initialize: function () {
this.items = new Models.Items()
.on('sync:subitems', function (item) {
this.subitems = new Models.Subitems({itemId: item.attributes.id});
And successfully receive it in initilize of model
var Subitems = Models.Subitems = Backbone.Collection.extend({
initialize: function(attributes, options) {
this.itemId = attributes.itemId;
console.log(this.itemId);
},
model: Subitem,
url: './subitems?item_id=' + encodeURIComponent(this.itemId)
});
console.log returns the value of attribute in initialize.
But request is sent like:
'./subitems?item_id=undefined'
Why do I have undefined if I have access to the property in initialize? How can it be fixed?
Change url to a function and you'll be in the context of the backbone collection as appose to the window.

How to send collection to another view?

Is there anyway to send backbone collection to another view without listenTo methods, to send it like an array or something else.
Im doing the fetch in the initialize function and then putting the collection in my array is that bad?
this.userModels = [];
this.collectionUser = new app.types.Users();
this.collectionUser.fetch();
this.userModels.push(this.collectionUser);
Im trying to send it like an array but on refreshing my web page sometimes im getting this
this.options child {
length: 15,
models: Array[15],
_byId: Object,
_listenId: "l4",
_events: Object…
}
and sometime getting with zero values
this.options child {
length: 0,
models: Array[0],
_byId: Object,
_listenId: "l4",
_events: Object…
}
So i wanna send my collection without listenTo method if it's possible.
First view:
app.types.FirstView = Backbone.View.extend({
initialize: function() {
this.collectionUser = new app.types.Users();
this.collectionUser.fetch();
};
sendCollection: function() {
var secondView = new app.types.SecondView({
collection: this.collectionUser
});
}
});
Second view:
app.types.SecondView = Backbone.View.extend({
initialize: function(options) {
this.collection = options.collection;
// so i want to get this.collectionUser here without listenTo
// method and without fetch here is that possible ? I said
// sometimes i get it sometimes not when i refersh my web page
// when i render it first time.
};
});
Yes you can send everything with js and use initialize for that view.
In your view you need to declare initialize function like this.
var someView = Backbone.View.extend({
template: _.template('some html file'),
initialize: function(options){
this.collection = options.collection
},
events: {
'click .someclass': 'doSomthing',
'click #someId': 'doSomthingElse'
},
doSomthing: function(event){
event.preventDefault();
var that = this;
that.collection.fetch({
success: function(){
that.$('element').append(that.collection);
}
});
},
render: function(){
var that = this;
that.$el.html(that.template);
return this;
}
});
And when u make new instance of your view need pass your collection as argument.
this.collectionUser = new app.types.Users();
this.view = new someView({collection: this.collectionUser});
This is it

Calling super class method in Backbone

var BaseView = Backbone.View.extend({
localizedTemplate : function (element) {
template = _.template(element.html());
return function (data) {
return template($.extend({}, data, resource));
};
}
});
var DerivedView = BaseView.extend({
initialize: function (options) {
this.model = options.model;
this.template = function () {
return this.localizedTemplate($("#someTemplate"));
};
},
render: function () {
var output = this.template(this.model.toJSON());
this.$el.append(output);
return this;
}
});
Why the above code is not working? why I am not able to call the someFunction in DerivedView? is there any way to achieve this?
I am using Backbone latest version.
When you do this:
this.template = function () {
return this.localizedTemplate($("#someTemplate"));
};
You're assigning a function to this.template. Note that localizedTemplate also returns a function:
return function (data) {
return template($.extend({}, data, resource));
};
That means that this.template is a function which returns a function and that second function is the one that wants this.model.toJSON() as an argument.
You're doing this:
var output = this.template(this.model.toJSON());
The function in this.template ignores its arguments and returns a function, that leaves you with this function:
function () {
return this.localizedTemplate($("#someTemplate"));
}
in output. You probably think output is a chunk of HTML at this point so you hand that to append:
this.$el.append(output);
But output is a function and what does append do when called with a function as its argument? jQuery calls that function like this:
function(index, html)
Type: Function()
A function that returns an HTML string, DOM element(s), or jQuery object to insert at the end of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set.
So the output function will be called by jQuery's append and append will supply arguments that the compiled template function doesn't understand. The result is a big pile of confusion.
If you really want to do things like this then you'll want to call all the functions yourself so that you can get the right arguments to the right places:
var output = this.template()(this.model.toJSON());
// -----------------------^^
Demo: http://jsfiddle.net/ambiguous/YyJLR/
Or better, don't bother with all the extra wrappers at all. Say this in your view's initialize:
this.template = this.localizedTemplate($("#someTemplate"));
and then this in render:
var output = this.template(this.model.toJSON());
Demo: http://jsfiddle.net/ambiguous/BQjhS/
Also note that you don't need to this.model = options.model, the view constructor will do that for you:
There are several special options that, if passed, will be attached directly to the view: model, collection, el, id, className, tagName and attributes.
var DerivedView = BaseView.extend({
someVariable: function(someData) {
return this.someFunction(someData);
}
});

Backbone.js view variables being overwritten

I am creating views via a $.each and the myId attribute of all the views always ends up being overwritten by the myId of the last element.
Creation of views
$('.form').each(function() {
// split class name
var classNameArray = $(this).attr('class').split('-');
// get typeId from last part of classname
var myId = classNameArray[classNameArray.length-1];
new myView({ 'el': $('.form-' + myId), 'myId': myId });
});
Initialization of my view
var myView = Backbone.View.extend({
events: {
},
initialize: function() {
var myId = this.options.myId;
},
test: function() {
console.log(myId); // will return myId of last view created
}
});
How can I get the views to keep their unique myId's?
When you write it like this --
initialize: function() {
var myId = this.options.myId;
},
It creates a variable local to the initialize function (that's a Javascript thing, not a Backbone thing).
Try this instead (create a variable local to the View object):
initialize: function() {
this.myId = this.options.myId;
},
test: function() {
console.log(myId); // will return myId of last view created
}
this [myId] is not the [myId] in :
initialize: function() {
var myId = this.options.myId;
}
it is the [myId] from :
$('.form').each(function() {
// split class name
var classNameArray = $(this).attr('class').split('-');
// get typeId from last part of classname
var myId = classNameArray[classNameArray.length-1]; //from this myId!!!
new myView({ 'el': $('.form-' + myId), 'myId': myId });
});
because:
first:
"var myId = this.options.myId; "
this [myId] is the initialize within the local variables,you can not access this variable outside the method.
second:
console.log(myId); // will return myId of last view created
why are we here be able to access to [myId]?because this [myId] is the [this.myId],[this] is the context of the calling method :
new myView({ 'el': $('.form-' + myId), 'myId': myId });
so,this [myId] is the :
var myId = classNameArray[classNameArray.length-1];
[myId] here.this [myId] is cyclic change, so you always get the last cycle the value of the [myId].
solution:
initialize: function() {
this.myId = this.options.myId;
},
because [this.myId] is [myView]'s internal variables, each time you create the instance of [myView], in the [initialize] method dynamically the [this.myId] is set to the correct value form [this.options.myId].
kind of problem, you can refer to this article:
http://dmitrysoshnikov.com/ecmascript/chapter-4-scope-chain

Passing arguments to init in ember.js

How can I pass arguments to init() or access the arguments passed to create() inside init() in ember.js
Just use this.get('theProperty')
Example:
var data = {
foo: "hello",
};
var MyModel = Em.Object.extend({
init: function() {
this._super();
var foo = this.get('foo');
alert(foo);
}
});
MyModel.create(data);
Use closures and create a new init function that passes the closed argument to its prototype init function. Also, this way you don't end up overwriting sensitive properties, like methods for example.
note: init is called after all the properties are set by the constructor
Class = Ember.Object.extend({
init:function(response){
console.log(this.get("msg")+this.get("msg_addressee")+"?");
console.log(response);
},
msg:"SUP, "
});
var arg = "not much.";
obj = Class.create({
init:function(){
console.log("output:");
this._super(arg);
console.log("indeed, "+arg);
},
msg_addressee:"dude"
});
//output:
//SUP, dude?
//not much.
//indeed, not much.

Categories

Resources