Extjs multiple representations of data - javascript

I have a Rest endpoint, that sends and receives objects of the form
[
{id: 1, Name: "Type"},
{id: 2, Name: "Type:Subtype"},
...
]
I want to display this in an editable tree, using Sencha Extjs 6. I am confused as to where and when to transform the data, and how to keep changes synchronized without side effects. My current (not nice) method is to reload the data and then reset the tree's store using the converted values, but that collapses all of the expanded nodes
I can get and save entries using a model and a store
I can convert the data into a form suitable for use in a treepanel
I do not know the "right" way to do so, and to have changes in either store reflected in the other.
For clarity, the converted tree store has a data stucture:
[
{
text: "Type",
children: [
{
text: "Subtype",
isLeaf: true
}
]
}
]

Came up with the answer: a save button.
Bound the Load event of the Rest Store to the controller, and in that method copied the values into the TreeStore.
Edits are made to the TreeStore - kept purely client side
Save button copies new data back into Rest Store and calls sync(). Easy to follow. Code is kept mostly declarative. And I can provide default values in the VM's data field. Easy to do - shame it's not made clear in the documentation somewhere

Related

Directly update mapbox source features

I'm drawing orders on the map using layers with symbols, this orders has status. Whenever the status changes I'd like to change de color of the symbol.
My layer has this configuration:
map.addLayer({
id: "orders",
type: "symbol",
source: "order-markers",
layout: {
"icon-image": [
"match",
["get", "orderStatus"],
"UNASSIGNED",
"unassigned-marker",
"ASSIGNED",
"assigned-marker",
"IN_TRANSIT",
"intransit-marker",
"CONCLUDED",
"concluded-marker",
"UNASSIGNED-marker",
],
},
});
});
Is there a recommended way to directly access the source and update the status in the properties object ? Or is it right to always overwrite the whole data object with setData ?
I tried to create a state in React with the features but it seems that the features object dont react to the state changes.
Thanks.
I haven't found a way to update a single property on a single feature. What I've always done is to overwrite the data as you've mentioned (i.e. map.getSource('order-markers').setData(/*...*/)) with the whole data object where a feature's property was changed. This is the method mapbox uses in their example for updating with live data: live-update-feature
As an alternative however, you can update a single feature's state. If that's a possibility you can use map.setFeatureState.
for example:
map.setFeatureState(
{
source: 'order-markers',
id: feature.id,
}, {
status: "IN_TRANSIT"
}
);
You'll then have to update your layer style/expressions to use the state instead of property to properly reflect the data as they are slightly different in how you get the values.

Redux data structuring

I'm trying to build a complex fully-dynamic app with Redux. I mean my App has lots of dynamic-generated forms with generated fields-components on-the-fly. I want to store in my Redux-store visual data about my components too. But how should i do it without mixing real data with visual component data?
For example if i have structure like this
Store {
visual: {...deeply nested visual-data-tree...},
data: {...deeply-nested real-data-tree...}
}
It is hard to render component because i need to search visual data first, then react component "value" in two trees.
But if have a structure similar to this:
Store {
form {
visual: {...form visual data...},
data: {
//Ok here the form "data" - widgets. Or it must to be visual? :)
widget1 {
visual: {type:"ComboBox", opened: true},
data: 1
}
}
}
}
You see the problem, now i have visual data inside real data of Form widget.
(form - data - widget1 - visual)
Visual data inside the real data is out of the concept.
How do you guys solve same problems of mixing data?
Really sorry for my poor english. I hope i clearly explained the problem.
Isn't the distinction superficial? I think a more important rule is that the data in the state should be normalized. For example, if you have Combobox widget letting you choose users, your data shape better be
{
chosenUserId: 10, // Good!
users: {
10: { name: 'Alice' }
}
rather than
{
chosenUser: { name: 'Alice' }, // Bad!
users: {
10: { name: 'Alice' }
}
If the data is duplicated in the state tree, it's hard to update it correctly and avoid inconsistencies.
As long as you keep the data normalized, I see no real need to divide visual and data. You might want to have top-level entity cache that looks like a database (e.g. entities which includes users, posts, or whatever data objects your app uses), but other than that, go with whatever state shape feels most comfortable when retrieving the relevant state.

Dojo JsonRestStore with array not at root-level of JSON response

Is there a way to configure a JsonRestStore to work with an existing web service that returns an array of objects which is not at the root-level of the JSON response?
My JSON response is currently similar to this:
{
message: "",
success: true,
data: [
{ name: "Bugs Bunny", id: 1 },
{ name: "Daffy Duck", id: 2 }
],
total: 2
}
I need to tell the JsonRestStore that it will find the rows under "data", but I can't see a way to do this from looking at the documentation. Schema seems like a possibility but I can't make sense of it through the docs (or what I find in Google).
My web services return data in a format expected by stores in Ext JS, but I can't refactor years worth of web services now (dealing with pagination via HTTP headers instead of query string values will probably be fun, too, but that's a problem for another day).
Thanks.
While it's only barely called out in the API docs, there is an internal method in dojox/data/JsonRestStore named _processResults that happens to be easily overridable for this purpose. It receives the data returned by the service and the original Deferred from the request, and is expected to return an object containing items and totalCount.
Based on your data above, something like this ought to work:
var CustomRestStore = declare(JsonRestStore, {
_processResults: function (results) {
return {
items: results.data,
totalCount: results.total
};
}
});
The idea with dojo/store is that reference stores are provided, but they are intended to be customized to match whatever data format you want. For example, https://github.com/sitepen/dojo-smore has a few additional stores (e.g. one that handles Csv data). These stores provide good examples for how to handle data that is offered under a different structure.
There's also the new dstore project, http://dstorejs.io/ , which is going to eventually replace dojo/store in Dojo 2, but works today against Dojo 1.x. This might be easier for creating a custom store to match your data structure.

ExtJS 5 - Dynamically add items to split button menu from store

I want to associate a store to split button menu. I am using extjs version 5. I have searched on the web and even went through sencha documentation but I couldn't figure out a way to achieve this.
Currently i'm holding the menu details in variable and assigning it to the splitbutton xtyoe menu property.I want to achieve the same using store, your help is much appreciated!
Program Code:-
var menuJSON = [{
text:'Menu1',
menu:[{text:'Submenu1'},{text:'Submenu2'}]
},{
text:'Menu2',
menu:[{text:'Submenu1'},{text:'Submenu2'}]
},{
text:'Menu3',
menu:[{text:'Submenu1'},{text:'Submenu2'}]
},{
text:'Menu4'
},{
text:'Menu5',
menu:[{text:'Submenu1'},{text:'Submenu2'}]
}];
{
region: 'south',
fbar: [{
xtype:'splitbutton',
id: 'app-starterMenu',
text:'Start',
scale:'small',
iconCls:'icon-start',
menuAlign: 'bl-tl',
menu: menuJSON
}]
}
Thanks in advance!
It would be helpful if you can provide example code for the store or relative controller, however this is still easier than you might think. Of course, it's nothing that comes out of the box, but it's a perfect case of using listeners.
Whenever the store changes data, you want to update your button configuration. Therefore just add the relevant listener to your store - maybe using the refresh or update event (depending on your specific use case). Then whenever the store data changes, you need to grab a reference to your button (or associated menu) and update the items. In it's most simplistic form, an example might be as follows:
store: {
listeners: {
refresh: function(store) {
// Get all the raw data from records and use it to set items on the menu
var rawData = Ext.Array.pluck(store.getRange(),'data');
Ext.getCmp('app-starterMenu').setMenu({
items: rawData
});
// *OR* Loop through the store data conditionally and include what you need
Ext.getCmp('app-starterMenu').getMenu().removeAll();
store.each(function(record){
Ext.getCmp('app-starterMenu').getMenu().add(record.getData());
});
}
}
}

d3.js save states

I use D3.js to visualize a couple of datasets in an interactive and dynamic way. Users can explore all graphs and retrieve individual views on the data by loading combining additional data and views. I want users to be able to share their treasure found in the data via mail, facebook etc. but in a way the new user, visiting the shared "snapshot" could move on exploring the data. So I need to
persist the current state of my dynamic webpage
be able to load and display this state fast.
bind all events that have been bound in the moment the user snapshot
As a as simple as possible example (there are going to be various graphs and lots of events), imagine having a simple d3 linegraph and
graph.selectAll("path").on('mouseover', function(d){
$.get("ajaxFunction",{"d" : d} ,function(jsonData) {
//INIT NEW SVG
});
});
This new dynamically loaded page contains i.e. several svgs. But if I simply save the shape and position of every svg, it could be hard to keep track of all current event-bindings.
And if I save every action the former user did, how could I reload the snapshot efficiently?
The simplest thing i can imagine would be looping over all the nodes storing their identity and their state as a hash then sending this hash as json using ajax back to the server and putting the hash in a databas along with a key that is returned to the user as an url.
when visiting the url you then load the d3js object and run through the hash setting the state of each node to what it was.
getting the state of the nodes would require some more knowledge in d3js.
What kind of data are you displaying? You should perhaps beable to add an event register to your js and record all the events executed. trough the event callers.
for instance say I have the following data
{"Things":{
"Balls":{
"Footballs":"",
"Basketballs":""
},
"Persons":{
"Painter":{
"Pablo":"","Robert":""
},
"Programmers":{
"Robert":""}}}
You should and want to show/hide nodes of this tree on mouse click.
You should be able to do somthing like this
var eventlog = [];
$(".nodes").onClick(function(this){
if (isClosed(this)){
function_to_open_node();
eventlog.append({"action" : "open", "id" : this.id})
}else{
function_to_close_node();
eventlog.append({"action" : "close", "id" : this.id})
}
})
This way you should end up with somthing like this
[{"action" : "close", "id" : "id"},{"action" : "close", "id" : "someotherid"},{"action" : "close", "id" : "someid"}]
Thus you have a storable state! that can be executed.

Categories