Why does the "fullName" function in this code execute twice?
Person = Ember.Object.extend({
// these will be supplied by `create`
firstName: null,
lastName: null,
fullName: function() {
console.log('Full name function...');
var firstName = this.get('firstName');
var lastName = this.get('lastName');
return firstName + ' ' + lastName;
}.property('firstName', 'lastName')
});
App.tom = Person.create({
firstName: "Tom",
lastName: "Dale"
});
App.UsersView = Ember.View.create({
templateName: 'users',
users: [App.tom]
});
Later in google-chrome console:
App.tom.set('firstName', 'John')
This outputs to log twice.
Seems like a bug, indeed (added a JSFiddle to illustrate: http://jsfiddle.net/MikeAski/GRvgt/)...
The view is rerendered, and the computed property not cached yet. :-(
Related
I'm trying to add a new record to an already existing array of objects.
The form works fine and when I press 'add' on the button, I get the values through.
However, I'm not able to create a new record, I get an error stating
this.init.apply(this, arguments); } has no method 'CreateRecord'".
Thank you for your help.
Here's my code:
App.Store = DS.Store.extend({
revision: 12,
adapter: 'DS.FixtureAdapter'
});
App.AddController = Ember.ObjectController.extend({
content: Ember.Object.create(),
addTo: function(obj){/*
App.Store.createRecord(
App.Post,
{
id: 3,
title: 'Created person',
author: 'dh2',
publishedAt: new Date('12-12-2003')
});*/
alert(JSON.stringify(obj) + "\n" + obj.title);
}
});
App.Post = DS.Model.extend({
title: DS.attr('string'),
author: DS.attr('string'),
publishedAt: DS.attr('date')
});
App.Post.FIXTURES = [
{
id:1,
title: "This is my title",
author: "John Doe",
publishedAt: new Date('12-27-2012')
},
{
id:2,
title: "This is another title",
author: "Jane Doe",
publishedAt: new Date('02-03-2013')
}
];
From inside a controller the store instance of your app is always available because it get's injected in every controller automatically by the framework, so you should access the store like this:
this.get('store').createRecord(App.Post, {...});
This should work correctly and not raise any errors.
Hope it helps.
I have collected data from fixture and displayed in form of table.
Also,i have added two column one is edit another is delete now i want to edit specific row.
On click of edit i have populated data on modal window with one update button and i want to update changes on click of update.
Here is my code :
Store :
Grid.Store = DS.Store.extend({adapter: 'DS.FixtureAdapter'});
Router:
Grid.Router.map(function () {
this.resource('mainview', { path: '/' });
});
Grid.MainviewRoute = Ember.Route.extend({
model: function () {
return Grid.ModalModel.find();
}
});
Model :
Grid.ModalModel = DS.Model.extend({
fname: DS.attr('string'),
lname: DS.attr('string'),
email: DS.attr('string'),
contactno: DS.attr('string'),
gendertype: DS.attr('boolean'),
contactype: DS.attr('number')
});
Grid.ModalModel.FIXTURES = [
{
id: 1,
fname: "sachin",
lname: "gh",
email: "gh",
contactno: "4542154",
gendertype: true,
contactype: 1
},
{
id: 2,
fname: "amit",
lname: "gh",
email: "gh",
contactno: "4542154",
gendertype: true,
contactype: 1
},
{
id: 3,
fname: "namit",
lname: "gh",
email: "gh",
contactno: "4542154",
gendertype: true,
contactype: 1
}
];
Controller :
Grid.MainviewController = Ember.ArrayController.extend({
contentChanged: function() {
this.get('content').forEach(function(item){
var serializer = DS.RESTSerializer.create();
var json_data = serializer.serialize(item);
console.log(JSON.stringify(json_data));
});
}.observes('content.#each'),
showmodal: function(){
$('#modal').modal();
},
showeditmodal: function(){
var rowindex_table = 1;
var contactype = 0;
var post = Grid.ModalModel.find(rowindex_table);
var serializer = DS.RESTSerializer.create();
var cont_edit_data = serializer.serialize(post);
console.log(JSON.stringify(cont_edit_data));
this.set('obj_form_edit_data.cont_data.fname', cont_edit_data["fname"]);
this.set('obj_form_edit_data.cont_data.lname', cont_edit_data["lname"]);
this.set('obj_form_edit_data.cont_data.email', cont_edit_data["email"]);
this.set('obj_form_edit_data.cont_data.contactno', cont_edit_data["contactno"]);
if(cont_edit_data["gendertype"] == true){
this.set('male', true);
$(".cssmale").addClass("active");
}else{
this.set('female', true);
$(".cssfemale").addClass("active");
}
$('.selectpicker').val(cont_edit_data['contactype']);
$('.selectpicker').selectpicker('render');
$('#editmodal').modal();
},
isMale: false,
isFemale: false,
obj_form_edit_data : Ember.Object.create({
cont_data:{
fname : "",
lname : "",
email : "",
contactno : "",
gendertype : "",
contactype : 0
}
}),
gendertype: function(){
this.set('isMale', !this.get('isMale'));
},
savecontact: function(){//save data in local storage
var fname = this.obj_form_edit_data.get('cont_data.fname');
var lname = this.obj_form_edit_data.get('cont_data.lname');
var email = this.obj_form_edit_data.get('cont_data.email');
var contactno = this.obj_form_edit_data.get('cont_data.contactno');
var gendertype = ((this.get('isMale') == true) ? true : false);
var contactype = $(".selectpicker").text();
//Clear view first
this.set('obj_form_edit_data.cont_data.fname', '');
this.set('obj_form_edit_data.cont_data.lname', '');
this.set('obj_form_edit_data.cont_data.email', '');
this.set('obj_form_edit_data.cont_data.contactno', '');
this.set('isMale',false);
this.set('isFemale',false);
$('.selectpicker').val('0');
$('.selectpicker').selectpicker('render');
Grid.ModalModel.createRecord({
fname: fname,
lname: lname,
email: email,
contactno: contactno,
gendertype: gendertype,
contactype: contactype
});
this.get('store').commit();
},
updatecontact: function(){
this.get('store').commit();
}
updatecontact is used to update record on click of update button but it is throwing an error
Uncaught TypeError: Object [object Object] has no method 'commit'
Can anyone tell me how to update record in such case?
When I save a User all current dirty Users are commited. What do I have to change that a save only commits the transaction for that specific User?
app.js
App = Ember.Application.create();
App.Store = DS.Store.extend({
revision: 12,
adapter: 'DS.FixtureAdapter'
})
App.Router.map(function() {
this.resource('users', function() {
this.resource('user', { path: ':user_id' })
})
});
App.UsersRoute = Ember.Route.extend({
model: function() {
return App.User.find();
}
});
App.UserController = Ember.ObjectController.extend({
startEditing: function() {
this.transaction = this.get('store').transaction();
this.transaction.add(this.get('content'));
},
save: function( user ) {
user.transaction.commit();
}
})
App.User = DS.Model.extend({
lastName: DS.attr('string')
})
App.User.FIXTURES = [{
id: 1,
lastName: "Clinton"
}, {
id: 2,
lastName: "Obama"
}]
My guess is that startEditing is never called, otherwise this would probably be ok.
The other option is that you save multiple times the record. Once a record is saved, it is moved back to the store's default transaction. Any subsequential call to save would actually commit the store's transaction.
Im trying to create a computed property to get me the sum of the length of all pages.
But i cannot figure out how to access a child so i can get the childs of that child.
App.Document = DS.Model.extend({
name: DS.attr('string'),
spreads: DS.hasMany('App.Spread'),
pagesCount: function() {
// Here is where i go wrong, i can get the length of spreads, but not access a spread to get the page length.
var spreadsLength = this.get('spreads.length');
var firstSpread = this.get('spreads')[0];
return firstSpread.get('pages.length');
}.property('spreads')
});
App.Spread = DS.Model.extend({
document: DS.belongsTo('App.Document'),
pages: DS.hasMany('App.Page')
})
App.Page = DS.Model.extend({
spread: DS.belongsTo('App.Spread'),
page_name: DS.attr('string'),
page_items: DS.hasMany('DS.PageItem')
})
Here is an example of how you get access to the first object in the array of spreads:
App.Document = DS.Model.extend({
name: DS.attr('string'),
spreads: DS.hasMany('App.Spread'),
pagesCount: function() {
// Here is where i go wrong, i can get the length of spreads, but not access a spread to get the page length.
var spreadsLength = this.get('spreads.length');
var firstSpread = this.get('spreads').objectAt(0);
// var firstSpread = this.get('spreads.firstObject'); // elegant way to first Object
return firstSpread.get('pages.length');
}.property('spreads.firstObject.pages.length')
});
But i guess you want to get the total number of pages here. So, here is an example how to iterate the spreads and sum the number of pages:
App.Document = DS.Model.extend({
name: DS.attr('string'),
spreads: DS.hasMany('App.Spread'),
pagesCount: function() {
// Here is where i go wrong, i can get the length of spreads, but not access a spread to get the page length.
var spreadsLength = this.get('spreads.length');
var ret = 0;
this.get("spreads").forEach(function(spread)){
ret += spread.get('pages.length');
}
return ret;
}.property('spreads.#each.pages.length')
});
Note: Look at the property dependency i declared via property. Since the ComputedProperty depend on those paths, you need to declare them there.
App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
email: DS.attr('st App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
email: DS.attr('string'),
phone: DS.attr('string'),
status: DS.attr('string', { defaultValue: 'new' }),
notes: DS.attr('string'),
// projects: DS.hasMany("project", {async: true}),
projectsCount: function() {
// alert(this.get('projects'));
return this.get('projects.length');
}.property('id'),
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName')
}.property('firstName', 'lastName')
}),
App.User.reopenClass({
valid: function(fields) {
return fields.firstName && fields.lastNameenter code here
}
});ring'),
phone: D App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
email: DS.attr('string'),
phone: DS.attr('string'),
status: DS.attr('string', { defaultValue: 'new' }),
notes: DS.attr('string'),
// projects: DS.hasMany("project", {async: true}),
projectsCount: function() {
// alert(this.get('projects'));
return this.get('projects.length');
}.property('id'),
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName')
}.property('firstName', 'lastName')
}),
App.User.reopenClass({
valid: function(fields) { App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
email: DS.attr('string'),
phone: DS.attr('string'),
status: DS.attr('string', { defaultValue: 'new' }),
notes: DS.attr('string'),
// projects: DS.hasMany("project", {async: true}),
projectsCount: function() {
// alert(this.get('projects'));
return this.get('projects.length');
}.property('id'),
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName')
}.property('firstName', 'lastName')
}),
App.User.reopenClass({
valid: function(fields) App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
email: DS.attr('string'),
phone: DS.attr('string'),
status: DS.attr('string', { defaultValue: 'new' }),
notes: DS.attr('string'),
// projects: DS.hasMany("project", {async: true}),
projectsCount: function() {
// alert(this.get('projects'));
return this.get('projects.length');
}.property('id'),
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName')
}.property('firstName', 'lastName')
}),
App.User.reopenClass({
valid: function(fields) {
return fields.firstName && fields.lastNameenter code here
}
}); {
return fields.firstName && fields.lastNameenter code here
}
});
return fields.firstName && fields.lastNameenter code here
}
});S.attr('string'),
status: DS.attr('string', { defaultValue: 'new' }),
notes: DS.attr('string'),
// projects: DS.hasMany("project", {async: true}),
projectsCount: function() {
// alert(this.get('projects'));
return this.get('projects.length');
}.property('id'),
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName')
}.property('firstName', 'lastName')
}),
App.User.reopenClass({
valid: function(fields) {
return fields.firstName && fields.lastNameenter code here
}
});
App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
email: DS.attr('string'), App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
email: DS.attr('string'),
phone: DS.attr('string'),
status: DS.attr('string', { defaultValue: 'new' }),
notes: DS.attr('string'),
// projects: DS.hasMany("project", {async: true}),
projectsCount: function() {
// alert(this.get('projects'));
return this.get('projects.length');
}.property('id'),
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName')
}.property('firstName', 'lastName')
}),
App.User.reopenClass({
valid: function(fields) {
return fields.firstName && fields.lastNameenter code here
}
});
phone: DS.attr('string'),
status: DS.attr(' App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
email: DS.attr('string'),
phone: DS.attr('string'),
status: DS.attr('string', { defaultValue: 'new' }),
notes: DS.attr('string'),
// projects: DS.hasMany("project", {async: true}),
projectsCount: function() {
// alert(this.get('projects'));
return this.get('projects.length');
}.property('id'),
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName')
}.property('firstName', 'lastName')
}),
App.User.reopenClass({
valid: function(fields) {
return fields.firstName && field App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
email: DS.attr('string'),
phone: DS.attr('string'),
status: DS.attr('string', { defaultValue: 'new' }),
notes: DS.attr('string'),
// projects: DS.hasMany("project", {async: true}),
projectsCount: function() {
// alert(this.get('projects'));
return this.get('projects.length');
}.property('id'),
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName')
}.property('firstName', 'lastName')
}),
App.User.reopenClass({
valid: function(fields) {
return fields.firstName && fields.lastNameenter code here
}
});s.lastNameenter code here
}
});string', { defaultValue: 'new' }),
notes: DS.attr('string'),
// projects: DS.hasMany("project", {async: true}),
projectsCount: function() {
// alert(this.get('projects'));
return this.get('projects.length');
}.property('id'),
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName')
}.property('firstName', 'lastName')
}),
App.User.reopenClass({
valid: function(fields) {
return fields.firstName && fields.lastNameenter code here
}
});
I have some thing like this:
window.App = Ember.Application.create();
App.Person = Ember.Object.extend({
id: null,
firstName: null,
lastName: null,
fullName: function() {
return this.get('firstName') + " " + this.get('lastName');
}.property('firstName', 'lastName')
});
App.selectedPersonController = Ember.Object.create({
person: null
});
App.selectedChildrenController = Ember.Object.create({
person: null
});
App.peopleController = Ember.ArrayController.create({
content: [
App.Person.create({
id: 1,
firstName: 'John',
lastName: 'Doe'
}),
App.Person.create({
id: 2,
firstName: 'Tom',
lastName: 'Cruise'
}),
App.Person.create({
id: 3,
firstName: 'Peter',
lastName: 'Pan'
}),
App.Person.create({
id: 4,
firstName: 'Sergey',
lastName: 'Brin'
})
]
});
App.childrenController = Ember.ArrayController.create({
children: [
App.Person.create({
person_id: 1,
firstName: 'Scott',
lastName: 'Hall'
}),
App.Person.create({
person_id: 1,
firstName: 'Jim',
lastName: 'Can'
}),
App.Person.create({
person_id: 2,
firstName: 'Will',
lastName: 'Smith'
}),
App.Person.create({
person_id: 4,
firstName: 'Bale',
lastName: 'Ron'
})
],
active: function() {
if (App.selectedPersonController.person) {
return this.get("children").filterProperty("person_id", App.selectedPersonController.person.id);
}
else {
return null;
}
}.property("App.selectedPersonController.person").cacheable()
});
window.App.Select = Ember.Select.extend({
contentChanged: function() {
this.$().selectBox('destroy').selectBox();
}.observes('content')
});
and my view code is something like this:
<script type="text/x-handlebars">
{{view window.App.Select
contentBinding="App.peopleController"
selectionBinding="App.selectedPersonController.person"
optionLabelPath="content.fullName"
optionValuePath="content.id"
prompt="Pick a person:"}}
{{view window.App.Select
contentBinding="App.childrenController.active"
selectionBinding="App.selectedChildrenController.person"
optionLabelPath="content.fullName"
optionValuePath="content.id"
prompt="Pick a child:"}}
<p>Selected: {{App.selectedPersonController.person.fullName}}
(ID: {{App.selectedPersonController.person.id}})</p>
</script>
I want my second window.App.Select to dynamically update depending on the selection in the first window.App.Select. I am using contentBinding="App.childrenController.active" for the second window.App.Select to make this work but what it does is that if I select a value in the person selectbox the child selectbox does not update, now when I select a different person from the person selectbox the child seletbox gets populated with the filtered values depending on my previous selection in the person select box.
Person selectbox -> select = John Doe (Nothing Happens)
Person selectbox -> select = Tom Cruise (Child select box gets filtered according to "John Doe" selection)
And so on.
Please see what is wrong with it.
I've put everything together again, in an attempt to restore Rajat's dead link into a working jsbin, implementing this version of the chained, or dependent, select boxes using ember.js/1.0.0-rc3.
http://jsbin.com/ixogag/5/