ExtJs 4.2 :: difference between "record" and "raw" in GRID - extjs

When I was playing with associations in ExtJs 4.2 MVC, I came across a problem for which I came up with a solution.
Problem Stmt: I have a grid page popullated with Model/Store : Issue. On click of the record on the grid, one should be able to see the comments which is another Model. Each Issue can have many comments.
Sample JSON:
{
"data": [
{
"id": 555,
"status": "OPEN",
"createDate": "04/29/2013",
"comments": [
{
"id": 1,
"commentDate": "19/02/2013",
"description": "Test"
},
{
"id": 2,
"commentDate": "29/01/2013",
"description": "Test 2"
}
]
}
],
"total": 1,
"success": true
}
Controller
Ext.define('app.IssuesC',
{
extend : 'Ext.app.Controller',
stores : [ 'IssuesS','CommentsS'],
models : [ 'IssueM', 'CommentsM'],
views : [ 'issue.IssueDetailV',
'issue.IssueGridV',
'issue.IssueCommentsV'],
refs : [ {
ref : 'comments',
selector : 'issuecomments'//xtype for issue.IssueCommentsV
}, {
ref : 'issuedetail',
selector : 'issuedetailv'//xtype for issue.IssueDetailV
}, {
ref : 'issuegrid',
selector : 'issuegrid'//xtype for issue.IssueGridV
} ],
onLaunch : function(app) {
this.control({
'issuegrid' : {
itemdblclick : this.onGridItemDblClick,
select : this.onSelectIssueShowComments
}
});
},
onGridItemDblClick : function(view, record, item, index, e) {
var IssueDetailV = Ext.widget('issuedetailv');
IssueDetailV.down('form').getForm().loadRecord(record);
},
onSelectIssueShowComments : function(selection,record, index, eOpts) {
this.getComments().setRecord(record.raw);
}
});
Model and association setup
Issue --> associations --> Comment
IssueM:
hasMany : {model:'CommetM',
name : 'commentsassociation'}
CommentM:
belongsTo : {model : 'IssueM'}
No issues any where. The views are perfectly fine. In the controller part on a single click, I am able to view the list of comments in a panel(placed below the main grid). I have used TPL property of XTemplate in the panel and it worked fine. What is this property "raw"? When I evaluate "record" in firebug it shows me "raw" "data" and many objetcs. The data part maps the name parameter and fills the values. The raw part has the same JSON structure and i have used it in retrieving the values for the panel. Is this the right way to do it?

Raw is just the raw JSON data that was sent down from the server. The configured reader then parses that raw payload and creates your record objects.
Readers are defined in store proxy: docs.sencha.com/extjs/4.1.3/#!/api/Ext.data.reader.Reader

"raw" gives as received from "back-end" but "record" gives the data but "transformed" through model(assuming you have some "formula" or "format" applied in "model"). Sorry for late reply!!

Related

How to Open Large Data using ng-href or ng-click in new window in AngularJS [duplicate]

This question already has an answer here:
How to Pass the data from Main Window to Child Window to display large data in table using AngulaJS
(1 answer)
Closed 6 years ago.
Can some one help me putting the DATA value new window .
I want to make td cell with DATA name as hyperlink . If I click that DATA it should open new window to show the value .
Demo
JSON Data
{
"58231e66982cf7857fee2cb5": {
"_id": {
"$id": "58231e66982cf7857fee2cb5"
},
"RECEIVETIME": {
"sec": 1478696550,
"usec": 529000
},
"OPERATION": "Operation 1",
"DATA" : "kdsjfkdjfkdjfkjdjfjdsfjdsilkjdkfljdsklfjkdlsjfkldsjflkdsjf",
"ACCOUNTNUMBER": "account",
"STATUS": "SUCCESS",
"MESSAGELOGCREATIONDATE": {
"sec": 1478696550,
"usec": 537000
}
},
"58231e681b58b970137b56aa": {
"_id": {
"$id": "58231e681b58b970137b56aa"
},
"RECEIVETIME": {
"sec": 1478696552,
"usec": 961000
},
"OPERATION": "Operation 2",
"DATA" : "dfdfdfkoooooooooooookdkfdkfodkfldkffdfd",
"ACCOUNTNUMBER": "account",
"STATUS": "FAIL",
"MESSAGELOGCREATIONDATE": {
"sec": 1478696552,
"usec": 961000
}
}
}
Currently I am using {{list.DATA}} show the data in the cell, But I want create hyperlink and once user clicks that link it should open new window to show the data. Since my DATA value is around 1000 lines. Can someone help me in approaching this.
And Is there way I can decode the Value of DATA in UTF-8 as the data value is encoded in UTF-8
Thanks in advance.
<tr class="features" ng-repeat="list in opMessageLogs">
<td>{{list._id.$id}}</td>
<td>{{list.OPERATION}}</td>
<td>{{list.STATUS}}</td>
<td>{{list.DATA}}</td>
</tr>
For a new tab, you need to create a link, but there's limit on a link (url) length, 2000 characters
Link here
what you can do is create a new route in angular that will take the param _id and then you can get the data by a http call or from service.
And for decoding/encoding utf-8
function encode_utf8(s) {
return unescape(encodeURIComponent(s));
}
function decode_utf8(s) {
return decodeURIComponent(escape(s));
}
Hope this helps..
To achieve this, you need to do following steps:
Create a state with a parameter i.e.
$stateProvider.state('openTab', {
'url' : '/link/:id',
'templateUrl': 'abc.html'
});
Use it this way in html.
<td> <a ui-sref="openTab({'id': list.DATA})" target="_blank">Click Here</a></td>

How to find documents in MongoDb matching a field and subdocument field that are in an array

The document structure is as follows:
{
"_id" : "V001-99999999",
"vendor_number" : "V001",
"created_time" : ISODate("2016-04-26T22:15:34Z"),
"updated_time" : ISODate("2016-06-07T21:45:46.413Z"),
"items" : [
{
"sku" : "99999999-1",
"status" : "ACTIVE",
"listing_status" : "LIVE",
"inventory" : 10,
"created_time" : ISODate("2016-05-14T22:15:34Z"),
"updated_time" : ISODate("2016-05-14T20:42:21.753Z"),
},
{
"sku" : "99999999-2",
"status" : "INACTIVE",
"listing_status" : "LIVE",
"inventory" : 10,
"created_time" : ISODate("2016-04-26T22:15:34Z"),
"updated_time" : ISODate("2016-06-06T20:42:21.753Z"),
}
]
}
I want to obtain the sku from the item, the conditions are:
1) "vendor_number" = "XXX"
2) items.status = "ACTIVE" AND items.updated_time < [given_date]
Result example:
"sku" : "99999999-2"
or csv:
"sku","99999999-2"
Thank you for your support.
This should be what you want. Although I'm assuming you wanted "status": "active"?
db.getCollection('collection').aggregate([
{ $match: { "vendor_number": "XXXX" } },
{ $project: {
"items": {
$filter: {
input: "$items",
as: "item",
cond: { $eq: ["$$item.status", "ACTIVE"] } // or maybe ["$$item.listing_status", "LIVE"] ?
}
}
}
},
{ $project: { "items.sku": true } }
])
I love using aggregation to manipulate stuff. It's great all the things you can do with it. So here's what's going on:
The first part is simple. The $match step in the aggregation pipeline says just give me documents where vendor_number is "XXXX".
The next part is a bit hairy. The first projection step creates a new field, called "items", I could have called it "results" or "bob" if I wanted to. The $filter specifies which items should go into this new field. The new "items" field will be an array that will have all the results from the previous items field, hence the input: "$items", where you're using the keyword "item" to represent each input item that comes into the filter. Next, the condition says, for each item, only put it in my new "items" array if the item's status is "ACTIVE". You can change it to ["$$items.listing_status", "LIVE"] if that's what you needed. All of this will pretty much give you you're result.
The last project just get's rid of all other fields except for items.sku in each element in the new "items" array.
Hope this help. Play around with it and see what else you can do with the collection and aggregation. Let me know if you need any more clarification. If you haven't used aggregation before, take a look at the aggregation docs and the list of pipeline operators you can use with aggregation. Pretty handy tool.

Using dot notation in Angular on JSON object not working as expected

I am being passed a JSON object via an API service. I have NO CONTROL over the format of the JSON. It is however a valid JSON object:
{
"Template" : {
"Parameters" : {
"Name" : "Test",
"Version" : "1.0"
},
"Fields" : {
"Field" : [{
"Prompt" : "Last Name:"
}, {
"Prompt" : "First Name:"
}, {
"Prompt" : "Middle Name"
}, {
"Prompt" : "ID Number:"
}
]
},
"Captures" : {
"Capture" : [{
"Prompt" : "Picture"
}, {
"Prompt" : "Picture from file"
}, {
"Prompt" : "Signature"
}
]
}
}
}
What I need to do is loop through a list of the Fields in the object, so that I can display values from there. In the case of this example, I am trying to print a list of Prompt values from the Fields.
http://jsfiddle.net/toddhd/0wbfpxkj/9/
<div ng-repeat="item in template.Fields.Field">
{{item.Prompt}}
</div>
This is explained MUCH better by looking at the JSFiddle above.
What I WANT to do is simply get the list of fields using dot/point notation, such as:
template.Fields.Field
But that isn't working for me. In the example, I also made a series of ng-repeats which loop through each collection one by one. That works and produces the desired result, but it's verbose and ugly.
I'm sure I'm just misunderstanding the structure of the JSON object itself, or maybe the correct dot/point notation to get there. But I just can't seem to figure it out. Can you please take a look and tell me where I'm going wrong?
Thank you
It's just missing another Template. It should be template.Template.Fields.Field.
Your html should look like this:
<div ng-repeat="item in template.Template.Fields.Field">{{item.Prompt}}</div>

Association ExtJs MVC 4.2

ExtJS 4.2 MVC: I have two models ServiceM and CommentsM. ServiceM has association(hasmany) with CommentsM. I DIDNOT forget to add the requires section ServiceM. Proxy is an ajax type defined in the model itself. I also created stores for each. Coming to the view, I have a grid for viewing all the services which are derived on loading the application. itemdblclick event is used to provide a detailed view about the service which is a window extending a form. The form is popullated by the below code:
var ServiceDetailV = Ext.widget('alias name of the service detail view');
ServiceDetailV.down('form').getForm().loadRecord(record);
I have two questions here.
When using developer tools in google chrome, in the above code I place debugger; at the end. I have highlighted the record, right clicked and evaluated that part. I see the data part and raw part. what is this raw part. It has all the data which the server is giving me(payload), even the nested comments section which is associated with the Service data.
I am able to popullate the fields in the form, but not the list of comments. the list of comments goes into a panel present in the form. How can I popullate the comments section.
JSON data:
{
"data": [
{
"id": 1,
"x": "some text",
"q": "some text",
"a": "some text",
"r":"some text",
"comments": [
{
"id": 87,
"commentDate": "date",
"description": "some text"
},
{
"id": 86,
"commentDate": "date",
"description": "some text"
}
]
} "total": 1,
"success": true}
Now, how can i access the comments field and poppulate the form with this data?
Please shed some knowledge on Associations ExtJs MVC.
Cheers!
Well, I took a step and got the solution for this. the raw parameter actually has the raw JSON payload. In the controller part I have handled it via a select event.
onSelectIssueShowComments : function(selection,record, index, eOpts) {
this.getComments().setRecord(record.raw);
}
I the view part
tpl : [ '<p>Previous Comments: ', '<tpl for="comments">',
'<p>{#}. {description} {commentDate}</p>', '</tpl></p>' ],
setRecord : function(record) {//this record here is record.raw
this.record = record;
if (record) {
this.update(record);
} else {
this.update(' ');
}
}
So it displays the array of comments in a Panel.

How do I show a value from model association in an ExtJS grid?

I am trying to draw a grid where each line is a stock's performance for a single day. In my data structures, I have a Date, a Stock, and a Stock Price resource. The store attached to my grid is the Stock Price store.
So, to the best of my understanding, my biggest problem is that when the grid cell renderers, I need to already have the value, or I need to have a blocking function to get a value.
When I use the getStore() magic function, I'm told the record doesn't know about it (undefined method). I'm assuming it's 'cause the record doesn't have the same functionality as a standalone model.
I see a few ways out of this:
Customise the grid and/or store so that when a load happens, all the related rows are loaded at the same time.
Create a callback in the renderer, and change the cell value afterwards, but I'm ot exactly sure how to do this. I don't actually want to change the cell value (StockId), just the visible output (Symbol).
Change my API to match my view.
Summing these up: #1 seems like a lot of work for a seemingly simple outcome. I keep trying to use the associations, but I'm finding they're not really useful for anything aside from little things here and there, and certainly not for lots of data. #2 I don't quite know where to begin at the moment; and #3 seems like massive overkill, and will generally ruin my server side as I will mean a few more joins, and more complexity when saving records as well.
So, two part question:
Does anyone know how to load a value from an associated model in a grid?
If not, to pique my curiosity, what sort of things are associations used for in any case where there's lots of data to deal with on screen? Lot's of data seems to be the reason to use Ext vs jQueryUI or some other UI framework, so I'm wondering what the associations are for.
Model - Stock Price
Ext.define('MyApp.model.StockPrice', {
extend : 'Ext.data.Model',
idProperty : 'StockPriceId',
fields : [ {
name : 'StockId',
type : 'int'
}, {
name : 'Open',
type : 'float'
}, {
name : 'Close',
type : 'float'
}, {
name : 'DateId',
type : 'date'
}],
proxy : {
type : 'rest',
url : '/api/stock.price'
},
reader : {
type : 'json'
},
associations : [ {
type : 'hasOne',
model : 'MyApp.model.Date',
primaryKey : 'DateId',
foreignKey: 'DateId'
},{
type : 'hasOne',
model : 'MyApp.model.Stock',
primaryKey : 'StockId',
foreignKey : 'StockId'
} ]
});
Model - Stock
Ext.define('MyApp.model.Stock', {
extend : 'Ext.data.Model',
idProperty : 'StockId',
fields : [ {
name : 'StockId',
type : 'int'
}, {
name : 'Symbol',
type : 'string'
} ],
proxy : {
type : 'rest',
url : '/api/stock'
},
reader : {
type : 'json'
},
associations : [ {
type : 'hasMany',
model : 'MyApp.model.StockPick',
primaryKey : 'StockId',
foreignKey : 'StockId'
}]
});
Model - Date
Ext.define('MyApp.model.Date', {
extend : 'Ext.data.Model',
fields : [ 'DateId', 'Date' ]
});
Store - Stock Price
Ext.define('MyApp.store.StockPrice', {
extend : 'Ext.data.Store',
model : 'MyApp.model.StockPrice',
remoteSort : true,
remoteFilter : true,
pageSize : 5,
autoLoad : true
});
View - Stock Price
Ext.define('MyApp.panel.StockData', {
extend : 'Ext.grid.Panel',
store : 'MyApp.store.StockPrice',
columns : [
{
text : 'Symbol',
flex : 1,
sortable : false,
hideable : false,
dataIndex : 'StockId',
renderer : function(stockId, metadata, stockPriceRecord) {
// What goes in here? PROBLEM POINT
MyApp.model.Stock.load(stockId, function() {
// ... some callback
});
// OR
return stockPriceRecord.getStock().get('Symbol');
}
},
{
text : 'Open',
flex : 1,
dataIndex : 'Open',
renderer : 'usMoney'
},
{
text : 'Close',
flex : 1,
dataIndex : 'Close',
renderer : 'usMoney'
},
{
text : 'Volume',
flex : 1,
dataIndex : 'Volume'
}]
});
Your only real option to display data from an associated model in a grid is to use a custom renderer function on the column. This will not change any values; it will simply render the desired output into the cell.
Now, as for implementing that renderer function: I would start by removing the proxies from the models and instead create stores for each model and allow the stores to manage the proxies -- then, attach the store for Stock as a listener on the store for StockPrice to listen for the datachanged event. When the data of the StockPrice store changes, you should grab every unique referenced Stock id and then tell the Stock store to request a payload of stocks with those ids.
That may mean altering your API a little bit to support a SQL IN(...) behind the scenes, but by leaving the joins to the client side you will put less stress on your server side.
In short, you need to use a little bit of all three ideas you came up with in order to best achieve your goal.

Resources