setActiveItem() passing data sencha touch - javascript

I would like to send data with setActiveItem() when doing view change from this store:
Ext.define('SkSe.store.Places',{
extend:'Ext.data.Store',
config:{
autoDestroy: true,
model:'SkSe.model.Places',
//hardcoded data
data: [
{
name: 'Caffe Bar XS', //naziv objekta
icon: 'Icon.png', //tu bi trebala ići ikona kategorije kojoj pripada
stamps: 'stamps1' //broj "stampova" koje je korisnik prikupio
},
{
name: 'Caffe Bar Mali medo',
icon: 'Icon.png',
stamps: 'stamps2'
},
{
name: 'Caffe Bar VIP',
icon: 'Icon.png',
stamps: 'stamps3'
}
]
//dynamic data (Matija)
//remember to change the icon path in "Akcije.js -> itemTpl"
/*proxy:{
type:'ajax',
url:'https://maps.googleapis.com/maps/api/place/search/json?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=AIzaSyCFWZSKDslql5GZR0OJlVcgoQJP1UKgZ5U',
reader:{
type:'json',
//name of array where the results are stored
rootProperty:'results'
}
}*/
}
});
This is my my details controller that should get data from places store:
Ext.define('SkSe.controller.Details', {
extend: 'Ext.app.Controller',
config: {
refs: {
placesContainer:'placesContainer',
Details: 'details'
},
control: {
//get me the list inside the places which is inside placesContainer
'placesContainer places list':{
itemsingletap:'onItemTap'
//itemtap:'onItemTap'
}
}
},
onItemTap:function(list,index,target,record){
console.log('omg');
var addcontact= Ext.create('SkSe.view.Details',
{
xtype:'details',
title:record.data.name,
data:record.data
});
var panelsArray = Ext.ComponentQuery.query('details');
console.log(panelsArray);
Ext.Viewport.add(addcontact);
addcontact.update(record.data.name);
Ext.Viewport.setActiveItem(addcontact);
console.log(record.data.name);
}
});
I would like to send name record from the places.js model above. I heard that you can't pass data with setActiveItem but should create a function that updates view(No I can't use pop and push here).
I'm not very familiar with sencha touch syntax and I'm not sure what functions to use to do that, clearly update function is not that.

I switched up your logic slightly but have provided a working example of what I think you are trying to do.
SenchaFiddle is a little different from what I get running on my machine but you should be able to get the idea.
The initial list loaded gets the data from your store, and on itemtap will push a new view onto the viewport.
You will need to add a navigation button to get back to the list from view.View as well as a better layout for the details. I would suggest nested containers or panels with custom styles to get the details just right. Alternatively you can just drop a full html snippet in there with all the data laid out like you want.
Would be happy to help more.
Fiddle: http://www.senchafiddle.com/#XQNA8

Related

Rally App SDK 2.0rc1 - Why does my combobox ignore datastore filters only on first click?

I have the following code (sloppy, I know...first javascript app). I am trying to get a combobox to populate with a list of features that fall under a given release (as selected in the first combobox). Almost everything is now working correctly, except everytime I click the feature combobox for the first time, it loads ALL features and completely ignores the filter. Even if I change the release box first, the feature box still populates with all features only on first click. Subsequent times it shows the correctly filtered features.
Even stranger, I've tried writing the total records in the Feature Store to the console, so I can see when this happens. When the feature combobox is first created, it has the correct number of records in it. However, as soon as I click the feature combobox for the first time, it triggers the "load" listener of the combobox, and pulls in all the features, ignoring the filter completely.
I'm so boggled, I've tried so many things to debug this, and at this point have no other options. Does anyone have any ideas as to why it would load the correct data first, then reload it and ignore the filters on first click?
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var relComboBox = Ext.create("Rally.ui.combobox.ReleaseComboBox", {
fieldLabel: 'Choose a Release',
width: 300,
listeners: {
ready: function(combobox) {
this._releaseRef = combobox.getRecord().get("_ref");
this._loadFeatureInfo();
},
select: function(combobox) {
this._releaseRef = combobox.getRecord().get("_ref");
this._loadFeatureInfo();
},
scope: this
}
});
this.add(relComboBox);
},
_loadFeatureInfo: function() {
var featureStore = Ext.create("Rally.data.WsapiDataStore", {
model: "portfolioitem/Feature",
fetch: ["Name", "_ref"],
autoLoad: true,
filters: [
{
property: "Release",
operator: "=",
value: this._releaseRef
}
],
listeners: {
load: function(store) {
this._updateFeatureBox(store);
},
scope: this
}
});
},
_createFeatureBox: function(featureStore) {
this._featureComboBox = Ext.create("Rally.ui.combobox.ComboBox", {
fieldLabel: 'Choose a Feature to move',
store: featureStore,
listeners: {
select: function (combobox) {
this._featureRef = combobox.getRecord().get("_ref");
//calls method to get and display children of this feature in a grid
},
scope: this
}
});
this.add(this._featureComboBox);
},
_updateFeatureBox: function(featureStore) {
if (this._featureComboBox === undefined) {
this._createFeatureBox(featureStore);
} else {
this._featureComboBox.clearValue();
this._featureComboBox.bindStore(featureStore);
//calls method to get and display children of this feature in a grid
}
}
This is probably an issue caused by the featureStore loading twice: once when you created it, and the combobox also tells it to load again once the user opens the combobox to pick a Feature.
I encountered a very similar issue with a combobox on Stories, and I'd betcha dollars to donuts that Matt Greer's answer:
Strange Load behavior with Rally.ui.combobox.ComboBox
To my question, is the answer to yours too...

Display JSON from sencha data store

I've searched and I can see this has been asked quite a few times, but I cant even figure out how to do a simple console.log on the data.
My store:
Ext.define('AventosPlanningTool.store.Aventos', {
extend:'Ext.data.Store',
config:
{
model:'AventosPlanningTool.model.Aventos',
proxy:
{
type:'ajax',
url:'resources/json/frames.json',
reader:
{
type:'json',
rootProperty:'options'
}
},
autoLoad: true
}
});
I can see in my network tab that the JSON file IS loading. I cannot figure out what to do with it at this point. In the data store, I've set the model to AventosPlanningTool.model.Aventos which is the file below.
Ext.define('AventosPlanningTool.model.Aventos', {
extend:'Ext.data.Model',
xtype:'AventosModel',
config:
{
fields: [
'name',
'image'
]
}
});
My JSON is pretty simple right now:
{
"name": "Cabinet Type",
"options": [
{
"name": "Face Frame",
"image": "resources/images/aventos/frames/faceframe.png"
},
{
"name": "Panel",
"image": "resources/images/aventos/frames/panel.png"
}
]
}
Even if I can do a console.log on the data that would be very helpful. I can't figure out how to use the data. I've checked both guides in the docs: http://docs-origin.sencha.com/touch/2.2.1/#!/guide/models, http://docs-origin.sencha.com/touch/2.2.1/#!/guide/stores and I just can't grasp it
Add a load listener to your store:
Ext.define('AventosPlanningTool.store.Aventos', {
extend:'Ext.data.Store',
config: {
model:'AventosPlanningTool.model.Aventos',
proxy: {
type:'ajax',
url:'resources/json/frames.json',
reader: {
type:'json',
rootProperty:'options'
}
},
autoLoad: true,
listeners: {
load: function(st, g, s, o, opts) {
st.each(function(record) {
console.log(record.get('name') + ' - ' + record.get('image'));
});
}
}
});
In sencha, data is defined in models, and actually memorized in stores. You can load your JSON through a proxy. Think of the model as the tables from sql and the store as the actual data in tables. Now, if you want to get the data from your store and perform operations on it, you have to load the store. To fetch your data into a list, you define a list with xtype:'list' specify your store store:'yourStoreName' and provide a template for showing that data. Here's a very detailed explanation on what I tried to say.
http://docs-origin.sencha.com/touch/2.2.1/#!/api/Ext.data.Store
also this:
http://miamicoder.com/2012/how-to-create-a-sencha-touch-2-app-part-2/
Look at the API docs for the data store. Note that you can only access the data once the store has been loaded. For example:
store.load();
store.getAt(0) // null, the store load hasn't completed yet.
You can loop over each record in the store using the each method. You can get a record at a particular index using getAt
store.each(function(rec) {
console.log(rec.get('name'), rec.get('image'));
});
console.log(store.getAt(0).get('name'));
Often times you will bind the store to a list, there are plenty of examples of this in the API docs.
I think what you're missing is to listen for the 'load' event on the store.
store.on('load', function(thisStore, records) {
console.log(records[0].get('name'));
})

Dynamically define and load views with different proxy store in Sencha Touch 2

I am creating a mobile application with Sencha Touch 2 that would load its views dinamically depending on a Json response from the server.
It means that before the load of the view I have to compose the view with some generic elements. For example, if I receive a Json string from the server corresponding to a List view I would have to dinamically fill the list items (name, url, descriprion) with a store and a proxy.
This works, but then I would like to select some item on that list and load another list, but this time I want to change the proxy. My new proxy is the url field from the selected item. I get the url field from the selected item and change the proxy, but this introduces a problem:
I am using an Ext.navigation.View, and I want to maintain navigation history. In the above case, if I go back in the navigation history the items on the first list change to the items on the last list.
I am searching for some kind of workflow to achieve dynamic load of the views depending on independent data for each one, and always maintaining the MVC-Store pattern and the navigation history.
This is my model for the list item:
Ext.define('ExampleApp.model.ListItem', {
extend: 'Ext.data.Model',
config: {
fields: ['name', 'url', 'descriprion']
}
}
This is the store for the List:
Ext.define('ExampleApp.store.ListItems', {
extend: 'Ext.data.Store',
config: {
autoLoad: false,
model: 'ExampleApp.model.ListItem',
proxy: {
type: 'jsonp'
url: 'http://mydomain.com/myjsonresponse',
reader: {
type: 'json',
useSimpleAccessors: true
}
}
}
})
This is my view:
Ext.define('ExampleApp.view.MyList', {
extend: 'Ext.List',
xtype: 'mylist',
requires: ['ExampleApp.store.ListItems'],
config: {
title: 'My List',
itemTpl: '{name} - {description}',
store: 'ListItems'
}
})
This is the function called on the itemtap event of my list:
listItemTapped: function (view, index, target, record, event) {
var listItems = Ext.getStore('ListItems');
listItems.getProxy().setUrl(record.get('url'));
listItems.load();
this.getMain().push({
xtype: mylist
});
}
What you can try is creating separate store for each list instead of reusing existing one.
listItemTapped: function (view, index, target, record, event) {
var listItems = Ext.create('ExampleApp.store.ListItems', {newUrl : record.get('url')});
listItems.load();
this.getMain().push({
xtype: mylist,
store: listItems
});
}
and add initialize function to use newUrl:
Ext.define('ExampleApp.store.ListItems', {
extend: 'Ext.data.Store',
config: {
autoLoad: false,
newUrl : null,
model: 'ExampleApp.model.ListItem'
},
initialize : function() {
this.setProxy({
type: 'jsonp'
url: this.config.newUrl,
reader: {
type: 'json',
useSimpleAccessors: true
}
});
}
})
You may want to destroy these stores once their view is popped.
#ThinkFloyd, agree that we need to destroy the store when we leave the view, as it will create a problem later when application has many views and has larger stores with lots of data. I recently face the same issue and this helps me a lot...thanks

How to make embedded hasMany relationships work with ember data

I can't get embedded hasMany to work correctly with ember data.
I have something like this
App.Post = DS.Model.extend({
comments: DS.hasMany('App.Comment')
});
App.Comment = DS.Model.extend({
post: DS.hasMany('App.Post'),
name: attr('string')
});
And my API returns the following for GET /post:
[
{
id: 1
comments: [{name: 'test'}, {name: 'test2'}]
},
...
]
I need to send this with POST /post:
[
{
comments: [{name: 'test'}, {name: 'test2'}]
},
...
]
I want to work with Ember models and have them make the appropriate requests:
var post = App.store.createRecord(App.Post, hash_post_without_comments);
post.get('comments').createRecord(hash_comment);
App.store.commit(); // This should call the POST api
and
var posts = App.store.find(App.Post); // This should call the GET api
When I try something like post: DS.hasMany('App.Post', {embedded: true}), the GET is working but the POST is trying to make a POST for the two records not only the parent one.
EDIT : My Real use case
1- I've just built ember data from master
2- My adapter: RESTAdapter
3- The serializer: JSONSerializer
4- I added
App.MyAdapter.map('App.Join', {
columns: { embedded: 'always' }
});
5- My Models are:
App.Join = DS.Model.extend({
rowCount: DS.attr('number'),
columns: DS.hasMany('App.JoinColumn'),
});
App.JoinColumn = DS.Model.extend({
join: DS.belongsTo('App.Join')
});
6- When:
var a = App.Join.find(1);
a.get('columns').createRecord({});
App.store.commit();
a POST for joincolumn is sent and the parent is not dirty
What am i missing?
On master, the correct API is:
App.Adapter.map('App.Post', {
comments: { embedded: 'always' }
});
The two possible values of embedded are:
load: The child records are embedded when loading, but should be saved as standalone records. In order for this to work, the child records must have an ID.
always: The child records are embedded when loading, and are saved embedded in the same record. This, of course, affects the dirtiness of the records (if the child record changes, the adapter will mark the parent record as dirty).
If you don't have a custom adapter, you can call map directly on DS.RESTAdapter:
DS.RESTAdapter.map('App.Post', {
comments: { embedded: 'always' }
});
I have the exact same problem.
This bug has been reported on the ember data issue tracker.
The following PR adds 2 failing tests showing the problem: https://github.com/emberjs/data/pull/578
It seems that there is no workaround right now.
EDIT:
sebastianseilund opened a PR 2 days ago which fixes your problem.
Have a look at: https://github.com/emberjs/data/pull/629/files
Adding an update to this incase others come across this post and are having a hard time figuring out what works with the current version of ember-data.
As of Ember Data 1.0.0.beta.7, you need to override the appropriate methods on the serializer. Here's an example:
1) Reopen the serializer (credit to this post):
DS.RESTSerializer.reopen({
serializeHasMany: function(record, json, relationship) {
var hasManyRecords, key;
key = relationship.key;
hasManyRecords = Ember.get(record, key);
if (hasManyRecords && relationship.options.embedded === "always") {
json[key] = [];
hasManyRecords.forEach(function(item, index) {
// use includeId: true if you want the id of each model on the hasMany relationship
json[key].push(item.serialize({ includeId: true }));
});
} else {
this._super(record, json, relationship);
}
}
});
2) Add the embedded: 'always' option to the relationship on the model:
App.Post = DS.Model.extend({
comments: DS.hasMany('comment', {
embedded: 'always'
})
});
This is what worked for me (Ember 1.5.1+pre.5349ffcb, Ember Data 1.0.0-beta.7.f87cba88):
App.Post = DS.Model.extend({
comments: DS.hasMany('comment', { embedded: 'always' })
});
App.PostSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
comments: { embedded: 'always' }
}
});

ExtJS: share store between grid and chart

I'm writing a simple application storing and displaying timestamped messages. Messages are JSON objects containing, say 2 main fields like:
{
"emitted": "2011-12-08 12:00:00",
"message": "This is message #666"
}
I have a model to describe these messages:
Ext.define('Message', {
extend: 'Ext.data.Model',
fields: [
{ name: 'emitted', type: 'date' },
{ name: 'message', type: 'string' }
]
});
I have no problem displaying these messages in a grid. However, i would now like to display these messages in a chart. For instance, I would be able to grab numbers (like the #666 in the above example) and display a line chart.
Ideally, i don't want to create a new store for the chart, i would like to reuse the same message store, but apply a filter on the fields to grab the proper value. I don't know, something that might look like:
var chart = {
xtype: 'chart',
...
series: [{
type: 'line',
axis: ['left', 'bottom'],
xField: 'emitted',
yField: {fieldName:'message', fieldGrabber: function(v) {
new RegExp("This is message #(\d+)$", "g").exec(v)[1]
}}
}]
};
Does this kind of thing is possible in ExtJS ?
I just tried to explain what I'm trying to do, i have no idea where to find such a feature: in the chart class, in the store class, or using a kind pf proxy to the store.
Side note:
I cannot ask the data to be properly formatted to the server. The messages I receive are not backed up anywhere, they are just live events streamed to the client via socketIO.
Any advices greatly appreciated!
You should extract the value inside you model to a separate field:
Ext.define('Message', {
extend: 'Ext.data.Model',
fields: [
{ name: 'emitted', type: 'date' },
{ name: 'message', type: 'string' },
{ name: 'nr', convert: function(v, r){
return r.get('message').replace(/^.*#/, '');
} }
]
});
Or you might be better off just having the 'nr' field and using a renderer in Grid that displays it as "This is message #{nr}".
Then you can use the 'nr' field directly in you chart.
I switched to Highcharts and threw ExtJS out to the trash :P

Categories