Ember model not displaying field data in template - ember.js

app/models/index.js
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend({
title: attr(),
owner: attr(),
city: attr(),
type: attr(),
image: attr(),
bedrooms: attr()
});
app/template/index.hbs
{{#each model as |rental|}}
<p>Location: {{rental.city}}</p>
<p>Number of bedrooms: {{rental.bedrooms}}</p>
{{/each}}
Am returning this from sinatra for the /rentals data request
{ data: [{
id: 1,
title: 'Grand Old Mansion',
owner: 'Veruca Salt',
city: 'San Francisco',
bedrooms: 15,
type: 'rental',
image: 'https://upload.wikimedia.org/wikipedia/commons/c/cb/Crane_estate_(5).jpg'
}, {
id: 2,
title: 'Urban Living',
owner: 'Mike TV',
city: 'Seattle',
bedrooms: 1,
type: 'rental',
image: 'https://upload.wikimedia.org/wikipedia/commons/0/0e/Alfonso_13_Highrise_T egucigalpa.jpg'
}, {
id: 3,
title: 'Downtown Charm',
owner: 'Violet Beauregarde',
city: 'Portland',
bedrooms: 3,
type: 'rental',
image: 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Wheeldon_Apartment_Bu ilding_-_Portland_Oregon.jpg'
}, {
id: 4,
title: 'xDowntown Charm',
owner: 'Violet Beauregarde',
city: 'Portland',
bedrooms: 3,
type: 'rental',
image: 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Wheeldon_Apartment_Building_-_Portland_Oregon.jpg'
}]}.to_json
the each loop knows how many records are there but the field data is missing as the browser shows this
Location:
Number of bedrooms:
Location:
Number of bedrooms:
Location:
Number of bedrooms:
Location:
Number of bedrooms:
Using ember 2.5

Per comment by dynamic_cast I changed the JSON structure to this and got it to work.
{
"data" => [{
"type" => "rentals",
"id" => "1",
"attributes" => {
"title" => 'Grand Old Mansion',
"owner" => 'Veruca Salt',
"city" => 'San Francisco',
"bedrooms" => 15,
"type" => 'rental',
"image" => 'https://upload.wikimedia.org/wikipedia/commons/c/cb/Crane_estate_(5).jpg'
}
},
{
"type" => "rentals",
"id" => "2",
"attributes" => {
"title" => 'Urban Living',
"owner" => 'Mike TV',
"city" => 'Seattle',
"bedrooms" => 1,
"type" => 'rental',
"image" => 'https://upload.wikimedia.org/wikipedia/commons/0/0e/Alfonso_13_Highrise_T egucigalpa.jpg'
}
},
{
"type" => "rentals",
"id" => "3",
"attributes" => {
"title" => 'Downtown Charm',
"owner" => 'Violet Beauregarde',
"city" => 'Portland',
"type" => 'Apartment',
"bedrooms" => 3,
"image" => 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Wheeldon_Apartment_Building_-_Portland_Oregon.jpg'
}
}
]
}.to_json

Related

Sencha Touch: show in a store's list a field of another store

I'm working on a Sencha Touch App. This App have 3 lists: clients, tasks and asignations. Each one has its own model and store. The 3rd one, asignations lists, is an asignations of a task to a client, so that list must show which task and client are asignated.
Models
Ext.define('TasksApp.model.Asignation',{
extend: 'Ext.data.Model',
config: {
idProperty: 'id',
fields: [
{name: 'asignID'},
{name: 'nombreasignacion', type: 'string'},
{name: 'clienteasignacion', type: 'string'},
{name: 'tareaasignacion', type: 'string'},
{name: 'finasignacion', type: 'date'},
{name: 'obsasignacion', type: 'string'},
{name: 'recordatorio', type: 'string'},
{name: 'estadoasignacion', type: 'string'}
],
}
});
Ext.define('TasksApp.model.Client',{
extend: 'Ext.data.Model',
config: {
idProperty: 'id',
fields: [
{name: 'clientID'},
{name: 'nombrecliente', type: 'string'},
{name: 'obscliente', type: 'string'},
{name: 'tlfcliente', type: 'int'},
{name: 'emailcliente', type: 'string'},
{name: 'urlcliente', type: 'string'},
{name: 'asigncliente', type: 'int', defaultValue: 0}
],
}
});
Ext.define('TasksApp.model.Task',{
extend: 'Ext.data.Model',
config:
{
idProperty: 'id',
fields: [
{name: 'tareaID'},
{name: 'nombretarea', type: 'string'},
{name: 'descripciontarea', type: 'string'},
{name: 'tdesarrollotarea', type: 'int'},
{name: 'asigntarea', type: 'int', defaultValue: 0}
],
}
});
Asignations List View + Asignation Template
var plantillaAsignacion = new Ext.XTemplate(
'<tpl for=".">',
'<div class="tplAsignacion">',
'<div class="asignacionCabecera">',
'<DIV ALIGN=center><B><I>{nombreasignacion}</i></B></DIV>',
'</div>',
'<div class="clienteCuerpo">',
'<div class="asignacionImagen" style= "float: left;"><img src="resources/images/asign_icon.png"/></div>',
'<ol>',
'<li><pre> Cliente: {clienteasignacion}</a></pre></li>',
'<li><pre> Tarea: {tareaasignacion}</pre></li>',
'<li><pre> Finalización: {finasignacion:date("d/m/Y")}<div align="right">Estado: {estadoasignacion} <span class="status {estadoasignacion}"></span> </pre></li>', //("l, F d, Y")("d/m/Y")
'</ol>',
'</div>',
'</div>',
'</tpl>'
);
Ext.define('TasksApp.view.AsignationsList', {
extend: 'Ext.Container',
requires: [ 'Ext.TitleBar', 'Ext.dataview.List' ],
alias: 'widget.asignationslistview',
config: {
layout: {
type: 'fit',
},
items:
[
{
xtype: 'titlebar',
title: 'Lista de asignaciones',
docked: 'top',
items:
[
{
xtype: 'button',
iconCls: 'add',
ui: 'action',
itemId: 'newButton',
align: 'right'
},{
xtype: 'button',
text: 'Clientes',
ui: 'action',
itemId: 'goToClients', iconCls: 'team',
align: 'left'
},
{
xtype: 'button',
text: 'Tareas',
ui: 'action',
itemId: 'goToTasks', iconCls: 'bookmarks',
align: 'left'
},
]
},
{
xtype: 'list',
store: 'Asignations',
itemId: 'asignationsList',
cls: 'estado-asignacion',
loadingText: 'Cargando Asignaciones...',
emptyText: 'No hay asignaciones actualmente',
onItemDisclosure: true,
//grouped: true,
itemTpl: plantillaAsignacion,
}
],
listeners:
[
{
delegate: '#newButton',
event: 'tap',
fn: 'onNewButtonTap'
},
{
delegate: '#asignationsList',
event: 'disclose',
fn: 'onAsignationsListDisclose'
},
{
delegate: '#goToClients',
event: 'tap',
fn: 'onGoToClients'
},
{
delegate: '#goToTasks',
event: 'tap',
fn: 'onGoToTasks'
}
]
},
onNewButtonTap: function () {
console.log('newAsignationCommand');
this.fireEvent('newAsignationCommand', this);
},
onAsignationsListDisclose: function (list, record, target, index, evt, options) {
console.log('editAsignationCommand');
this.fireEvent('editAsignationCommand', this, record);
},
onGoToClients: function () {
console.log ('goToClientsCommand');
this.fireEvent('goToClientsCommand', this);
},
onGoToTasks: function () {
console.log ('goToTasksCommand');
this.fireEvent('goToTasksCommand', this);
}
});
Asignation Editor View ( form of the asignation )
Ext.define('TasksApp.view.AsignationEditor', {
extend: 'Ext.form.Panel',
requires: [
'Ext.TitleBar', 'Ext.form.FieldSet', 'Ext.field.Text','Ext.field.Select', 'Ext.field.DatePicker', 'Ext.field.TextArea','Ext.form.Panel'
],
alias: 'widget.asignationeditorview',
config: {
scrollable: 'vertical',
items:
[
{
xtype: 'titlebar',
docked: 'top',
title: 'Editar Asignación',
items:
[
{
xtype: 'button',
ui: 'back',
text: 'Volver',
itemId: 'backButton',
align: 'left'
},
{
xtype: 'button',
ui: 'action',
text: 'Guardar',
itemId: 'saveButton',
align: 'right'
}
]
},
{
xtype: 'toolbar',
docked: 'bottom',
items: [
{
xtype: 'button',
iconCls: 'trash',
iconMask: true,
itemId: 'deleteButton'
}
]
},
{
xtype: 'fieldset',
items:
[
{
xtype: 'textfield',
name: 'nombreasignacion',
label: 'Nombre',
required: true,
autoCapitalize: true,
placeHolder: 'Nombre de la asignación...'
},
{
xtype: 'selectfield',
name: 'clienteasignacion',
label: 'Cliente',
valueField: 'clientID',
displayField: 'nombrecliente',
store: 'Clients',
autoSelect: false,
placeHolder: 'Seleccione un cliente...',
required: true,
},
{
xtype: 'selectfield',
name: 'tareaasignacion',
label: 'Tarea',
valueField: 'tareaID',
displayField: 'nombretarea',
store: 'Tasks',
autoSelect: false,
placeHolder: 'Seleccione una tarea...',
required: true,
},
{
xtype: 'datepickerfield',
name: 'finasignacion',
label: 'Vencimiento',
dateFormat: 'd/m/Y',
value: (new Date()),
picker:
{
yearFrom: new Date().getFullYear(),
yearTo: 2040,
slotOrder: [ 'day', 'month', 'year' ]
}
},
{
xtype: 'textareafield',
name: 'obsasignacion',
label: 'Observaciones',
autoCapitalize: true,
autoCorrect: true,
placeHolder: 'Observaciones de la asignación...',
maxRows: 5
},
{
xtype: 'selectfield',
name: 'recordatorio',
label: 'Recordatorio',
autoSelect: true,
placeHolder: 'Seleccione el método recordatorio...',
required: true,
options:
[
{
text: 'Ninguno',
value: 0
},
{
text: 'eMail',
value: 2
},
{
text: 'SMS',
value: 1
},
{
text: 'Notificación',
value: 3
}
]
},
{
xtype: 'selectfield',
name: 'estadoasignacion',
label: 'Estado',
autoSelect: true,
placeHolder: 'Seleccione el estado...',
required: true,
options:
[
{
text: 'Activa',
value: 'Activa'
},
{
text: 'Caducada',
value: 'Caducada'
},
{
text: 'Cancelada',
value: 'Cancelada'
},
{
text: 'Realizada',
value: 'Realizada'
}
]
},
]
}
],
listeners: [
{
delegate: '#saveButton',
event: 'tap',
fn: 'onSaveButtonTap'
},
{
delegate: '#deleteButton',
event: 'tap',
fn: 'onDeleteButtonTap'
},
{
delegate: '#backButton',
event: 'tap',
fn: 'onBackButtonTap'
}
]
},
onSaveButtonTap: function () {
console.log('saveAsignationCommand');
this.fireEvent('saveAsignationCommand', this);
},
onDeleteButtonTap: function () {
console.log('deleteAsignationCommand');
this.fireEvent('deleteAsignationCommand', this);
},
onBackButtonTap: function () {
console.log('backToHomeCommand');
this.fireEvent('backToHomeCommand', this);
}
});
Asignation Controller
Ext.define('TasksApp.controller.Asignations', {
extend: 'Ext.app.Controller',
config: {
refs: {
asignationsListView: 'asignationslistview',
asignationEditorView: 'asignationeditorview'
},
control: {
asignationsListView: {
newAsignationCommand: 'onNewAsignationCommand',
editAsignationCommand: 'onEditAsignationCommand'
},
asignationEditorView: {
saveAsignationCommand: 'onSaveAsignationCommand',
deleteAsignationCommand: 'onDeleteAsignationCommand',
backToHomeCommand: 'onBackToHomeCommand'
}
}
},
getSlideLeftTransition: function () {
return { type: 'slide', direction: 'left' };
},
getSlideRightTransition: function () {
return { type: 'slide', direction: 'right' };
},
getRandomInt: function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
activateAsignationEditor: function (record) {
var asignationEditorView = this.getAsignationEditorView();
asignationEditorView.setRecord(record); // load() is deprecated.
Ext.Viewport.animateActiveItem(asignationEditorView, this.getSlideLeftTransition());
},
activateAsignationsList: function () {
Ext.Viewport.animateActiveItem(this.getAsignationsListView(), this.getSlideRightTransition());
},
onNewAsignationCommand: function () {
console.log('onNewAsignationCommand');
var now = new Date();
var asignationId = (now.getTime()).toString() + (this.getRandomInt(0, 100)).toString();
var newAsignation = Ext.create('TasksApp.model.Asignation', {
id: asignationId,
nombreasignacion: '',
clienteasignacion: '',
tareaasignacion: '',
finasignacion: '',
obsasignacion: '',
recordatorio: '',
estadoasignacion: ''
});
this.activateAsignationEditor(newAsignation);
},
onEditAsignationCommand: function (list, record) {
console.log('onEditAsignationCommand');
this.activateAsignationEditor(record);
},
onSaveAsignationCommand: function () {
console.log('onSaveAsignationCommand');
var asignationEditorView = this.getAsignationEditorView();
var currentAsignation = asignationEditorView.getRecord();
var newValues = asignationEditorView.getValues();
currentAsignation.set('nombreasignacion', newValues.nombreasignacion);
currentAsignation.set('clienteasignacion.nombrecliente', newValues.clienteasignacion);
currentAsignation.set('tareaasignacion.nombretarea', newValues.tareaasignacion);
currentAsignation.set('finasignacion', newValues.finasignacion);
currentAsignation.set('obsasignacion', newValues.obsasignacion);
currentAsignation.set('recordatorio', newValues.recordatorio);
currentAsignation.set('estadoasignacion', newValues.estadoasignacion);
var asignationsStore = Ext.getStore('Asignations');
if (null == asignationsStore.findRecord('id', currentAsignation.data.id)) {
asignationsStore.add(currentAsignation);
}
asignationsStore.sync();
asignationsStore.sort([{ property: 'dateCreated', direction: 'DESC'}]);
this.activateAsignationsList();
},
onDeleteAsignationCommand: function () {
console.log('onDeleteAsignationCommand');
var asignationEditorView = this.getAsignationEditorView();
var currentAsignation = asignationEditorView.getRecord();
var asignationsStore = Ext.getStore('Asignations');
asignationsStore.remove(currentAsignation);
asignationsStore.sync();
this.activateAsignationsList();
},
onBackToHomeCommand: function () {
console.log('onBackToHomeCommand');
this.activateAsignationsList();
},
launch: function () {
this.callParent(arguments);
var asignationsStore = Ext.getStore('Asignations');
asignationsStore.load();
console.log('launch');
},
init: function () {
this.callParent(arguments);
console.log('init');
}
});
I want the asignations list to show the client name ( nombrecliente ) and the task name ( nombretarea ), but it shows nothing at all. I don't know how to refer to this values so the list shows them. I tried to modify the asignations controller, the selectfield int the asignation editor ( form ) and the asignations template, but I simply don't know how this works and what I have to do to show that values ( if they are saved in the asignations store at this moment via selectfield, or am I doing anything wrong? )
I would appreciate any help. Thank you in advance.
PS: sorry for my English, it's not my native language :)
Please create array in the key value pair with the key name as your model field and then set that data into your asign Asignations store like:
Asignations.setdata({fieldName:"value"});

Not display the list view on mobile app developed by sencha touch2

I have made a sencha touch app. The app contains list. When I run the app in my computer browser, the list will appear properly. But when I run it on android mobile browser or as a android mobile app the list does not appear. The code as follows:
Model:
Ext.define('Proximity.model.CandidatebestlistModel', {
extend: 'Ext.data.Model',
config: {
store: 'Proximity.store.CandidatebestStore',
fields: [{
name: 'id',
type: 'int'
},
{
name: 'name',
type: 'string'
},
{
name: 'img',
type: 'string'
},
{
name: 'designation',
type: 'string'
},
{
name: 'summary',
type: 'string'
},
{
name: 'experience',
type: 'string'
},
{
name: 'industry',
type: 'string'
},
{
name: 'functionnml',
type: 'string'
},
{
name: 'role',
type: 'string'
}
],
proxy: {
type: 'ajax',
url: Proximity.app.baseUrl + '/index.php/candidate/getcandidatebest',
withCredentials: false,
useDefaultXhrHeader: false,
extraParams: {
"id": localStorage.getItem('id')
},
reader: {
filters: [
Ext.create('Ext.util.Filter', {
property: 'ind_id',
property: 'fun_id',
property: 'role_id'
})
]
}
}
}
});
Store:
Ext.define('Proximity.store.CandidatebestStore', {
extend: 'Ext.data.Store',
alias: 'store.candidatebeststore',
config: {
model: 'Proximity.model.CandidatebestlistModel',
autoLoad: true,
remoteFilter: true,
storeId: 'candidatebeststore'
}
});
View:
{
width: Ext.os.deviceType == 'Phone' ? null : '100%',
height: Ext.os.deviceType == 'Phone' ? null : '100%',
xtype: 'list',
itemId: 'list',
store: 'candidatebeststore',
masked: {
xtype: 'loadmask',
message: 'Please wait... '
},
emptyText: 'No List Item Found',
disableSelection: false,
itemTpl: '{name}
'+
'{designation} {
summary
} {
experience
}
Years Experience '+
'',
listeners: {
select: function(view, record) {
Proximity.app.getController('CandidatelistController').onDetailsview(record.get('id'));
}
}
}
For additional information:-- I place this list inside the tab panel. So Please give me some solution of this problem.
Thank You.
In the following line of codes
width: Ext.os.deviceType == 'Phone' ? null : '100%',
height: Ext.os.deviceType == 'Phone' ? null : '100%',
replace null with '100%'.

Sideload with ember

Can someone explain why the side loading in this case don't work, I dont get any errors but the followers are not rendered and when I try to check it in the setupController method using model.get('followers').content, I got an empty array.
This is the loaded JSON:
{
user: {
id: 1,
follower_ids: [2,3,4],
name: 'someUserName'
}
followers: [
{
id: 2,
name: 'someUserName'
},
{
id: 3,
name: 'someUserName'
},
{
id: 4,
name: 'someUserName'
}
]
}
and this is my User model
App.User = DS.Model.extend({
name: DS.attr('string'),
followers: DS.hasMany('App.User')
});
Unlike the guide shows, the key for the ids must be followers instead of follower_ids. So with a JSON look like this it works:
{
user: {
id: 1,
followers: [2,3,4],
name: 'someUserName'
}
followers: [
{
id: 2,
name: 'someUserName'
},
{
id: 3,
name: 'someUserName'
},
{
id: 4,
name: 'someUserName'
}
]
}

Sideload a lists "belongsTo" objects with EmberData

I have 3 emberData models:
App.Product = DS.Model.extend({
page_title: DS.attr('string'),
shop: DS.belongsTo('App.Shop'),
user: DS.belongsTo('App.User')
});
App.Shop = DS.Model.extend({
name: DS.attr('string'),
});
App.User = DS.Model.extend({
name: DS.attr('string')
});
and the JSON data looks like this:
{
products: [
{
id: "1",
page_title: "Product 1",
user_id: "1",
shop_id: "1",
},
{
id: "2",
page_title: "Product 2",
user_id: "2",
shop_id: "1",
}
],
users: [
{
id: "1",
name: "User 1"
},
{
id: "2",
name: "User 2"
}
],
shops: [
{
id: "1",
name: "Shop 1"
}
]
}
But when I load the data I got the following error:
Assertion failed: Your server returned a hash with the key shops but you have no mapping for it
Ok, the documentaion is very unclear about the fact that when you have a belongsTo relationship the key for the sideload must be singular not plural even if its a list. So the JSON has to look like this:
{
products: [
{
id: "1",
page_title: "Product 1",
user_id: "1",
shop_id: "1",
},
{
id: "2",
page_title: "Product 2",
user_id: "2",
shop_id: "1",
}
],
user: [
{
id: "1",
name: "User 1"
},
{
id: "2",
name: "User 2"
}
],
shop: [
{
id: "1",
name: "Shop 1"
}
]
}

List paging from json

I am finaly able to retrieve my datas from the json file BUT the paging system still sucks. The pageSize property seems not to respond therefore when i press on the load more plugin text that appears at the bottom of my list, it appends all my json elements to my list everytime. I am confident about the fact that i am almost there but i can't see how to make it happen.
Here is the code:
Ext.setup({
tabletStartupScreen: 'tablet_startup.png',
phoneStartupScreen: 'phone_startup.png',
icon: 'icon.png',
glossOnIcon: false,
onReady : function() {
var dataLink;
if (Ext.is.Desktop) {
dataLink = "http://127.0.0.1/Appsfan-v2";
} else {
dataLink = "http://appsfan.kreactive.eu";
}
Ext.regModel('Profile', {
fields: [
{name: 'firstname', type: 'string'},
{name: 'lastname', type: 'string'},
{name: 'age', type: 'number'}
]
});
var store = new Ext.data.JsonStore({
model: 'Profile',
autoLoad: false,
remoteFilter: true,
sortOnFilter: true,
//sorters: [{property : 'lastname', direction: 'ASC'}],
pageSize: 1,
clearOnPageLoad: false,
proxy: {
type: 'ajax',
url: dataLink+'/data.json',
reader: {
root: 'profile',
type: 'tree'
}
}
});
console.log(store)
//console.log(store.loadPage(0))
var groupingBase = new Ext.List({
fullscreen: true,
itemTpl: '<div class="contact2"><strong>{firstname}</strong> {lastname} -> {age}</div>',
indexBar: false,
store: store,
plugins: [{
ptype: 'listpaging',
autoPaging: false
}]
});
var panel = new Ext.Panel({
layout: 'card',
fullscreen: true,
items: [groupingBase],
dockedItems: [{
xtype: 'toolbar',
title: 'paging example',
}]
})
//console.log(datas)
}
});
The json
{
"profile": [{
"firstname": "firstname1",
"lastname": "lastname1",
"age": "1"
},{
"firstname": "firstname2",
"lastname": "lastname2",
"age": "2"
},{
"firstname": "firstname3",
"lastname": "lastname3",
"age": "3"
}]
}
Thank you
You can set the clearOnPageLoad config option in your store. This will remove previous records when the next page of the paginated data is loaded.
Here is an example:
Ext.regStore('BarginsStore', {
model: 'BarginModel',
autoLoad: false,
pageSize: 6,
clearOnPageLoad: false,
});