I need to load JSON data into a Tree or TreePanel.
The JSON data does not come from a file or retrived from a URL but is built on the fly.
I cannot find any examples.
Can anyone help?
While I was trying to create a Treegrid afetr searching something in a search filed (need to pass this in the URL) i found some strange behaviour.
How I created here is the logic:
Created a Tree class with rootVisible: false and store:mystore
My store has no proxy{} as I had to set this dynamically from controller
Inside the store autoLoad:false was there
Used mystore.load() to load the data into tree
Request was going for 2 times
A blank root node in the tree although I have no root node.
I fixed it in the following way... not sure to wat extend this is correct. Any better solution please share
Tree class(View)
Didn’t define any treestore inside tree view
rootVisible: false
Inside the controller
search: function(button){
var searchText = this.getSearchField().value;
//created a store instance
var mystore = Ext.data.StoreManager.lookup('MyTreeStore');
mystore.setProxy({
type: 'ajax',
url: 'app/searchid/'+searchText;
});
var mytree = Ext.create('AM.view.MyTree',{store:mystore});
Ext.getCmp('tn').add(mytree);
//DON’T USE store.load() method As we have set rootVisible: false so it will automatically try to load the store or will send the request
}
Store file
Ext.define('AM.store.BomTreeStore', {
extend: 'Ext.data.TreeStore',
model: 'AM.model.BomTree',
autoLoad: false,
folderSort: true
});
Any better solution to this plz share :)
You can do it by progammatically creating a root node.
Iterate through your data and keep appending child nodes to your root node.
It has been explained quite well here:
ExtJS: How to create static and dynamic trees
Related
I am currently using AngularFire, and trying to get the length of objects in my database.
In my Firebase, the structure looks like
popping-fire-5575
celio
-JgaQt-tNq-gRVIVZdCD
artist:
track:
-JgaQuBoYk9VX3pWylx3
artist:
track:
-JgaQuf_pyBFJ7EA1Fo_
artist:
track:
In my controller,
var profileObject = FirebaseDemo.getBroadcast($routeParams.param);
var twotwo = profileObject.$asObject();
twotwo.$bindTo($scope, 'data');
When I console log the variable 'twotwo',
I get in return
Object
$$conf: Object
$id: "celio"
$priority: null
-JgaQt-tNq-gRVIVZdCD: Object
-JgaQuBoYk9VX3pWylx3: Object
-JgaQuf_pyBFJ7EA1Fo_: Object
__proto__: Object
However, I have tried all different ways to get the length, but I am not able to get to succeed. Could someone give me some directions or tips?
Firebase loads (and synchronizes) you data asynchronously, so by the time your console.log statement runs it is probably still busy loading the data.
Luckily AngularFire has a way to notify and run your code when the initial loading of data has completed:
var twotwo = profileObject.$asArray();
twotwo.$loaded().then(function(data) {
console.log('Initial data loaded', data.length);
});
The two main changes from your code:
Use $asArray() instead of $asObject(), since your data structure is an array
Listen for the $loaded "event" and respond to that
Note that AngularFire will already notify AngularJS of any changes to the data, so you won't have to respond to $loaded if you just bind the data to the $scope and show it in your view.
I am learning ExtJS-4.2, I was following their MVC tutorial...
I built my controller, view, model, store... My Store had hard-coded data. I have a working WebAPI for testing, which sends result in json format...
What the tutorial is talking about how to read from local file and send to an API,
what i want to read from API and load my data into the store...
Ext.define('AM.store.Productstore',
{
extend : 'Ext.data.Store',
model : 'AM.model.Productmodel',
autoload : true,
proxy : {
type : 'AJAX',
url : 'localhost/mfw/api/products/all'
//tutorial is no help any furthur from this point on
}
});
My URL is localhost/mfw/api/products/all
and my returning json is
[{"ID":1,"Name":"aa","Category":"A","Price":200.00},
{"ID":2,"Name":"bb","Category":"B","Price":200.00
{"ID":3,"Name":"cc","Category":"C","Price":200.00},
{"ID":4,"Name":"dd","Category":"D","Price":200.00},
{"ID":5,"Name":"ee","Category":"E","Price":200.00},
{"ID":6,"Name":"ee","Category":"F","Price":200.00}]
any help?
Please change your proxy type to 'rest' instead of 'Ajax'. More over mention your reader config. Did you map your json key with fields in model.
please refer sencha guide for more clarity.
http://docs.sencha.com/ext-js/4-2/#!/guide/data
Thanks
Here is a jsfiddle showing a grid with your data. One of the key things is the root property of the json reader. Since your data does not have a root you can leave the root property out and it should work. If you data is wrapped inside another field ie root field then specify root: 'myrootfield' in the reader. So here is your proxy. Also in your model specify the key field using idProperty in your case it is 'ID', I think extjs defaults to idProperty of 'id' lowercase so better to just specify it directly.
proxy : {
type : 'rest',
url : 'localhost/mfw/api/products/all'
reader: {
type: 'json'
}
}
I'm learning both CoffeeScript and Backbone JS. I want to load just one piece of equipment. Yes, I know I don't need Backbone JS for this - But it helps me to learn if I start with basics. As soon as the page loads, I want it to grab some JSON from the server, and display it on the page.
Here is my coffeescript so far:
jQuery ->
class Equipment extends Backbone.Model
defaults:
title:''
desc:''
url:'/getData'
class ItemView extends Backbone.View
tagName: 'div'
initialize: ->
_.bindAll #, 'render'
render: ->
$(#el).html """
<h1>#{#model.get 'title'}</h2>
<p>#{#model.get 'desc'}</p>
"""
#
class AppRouter extends Backbone.Router.extend
routes:
'':'getData'
getData: ->
#equipment = new #Equipment()
#equipmentView = new #ItemView
model: #equipment
#equipment.fetch()
$('div').html #equipmentView.render().el
appRouter = new AppRouter
Backbone.history.start()
I feel like I have all the pieces in place, and am getting no errors (either in compilation or running the page).
The basic JSON I expect back from the server is just a PHP page echoing this:
{
"title": "title",
"desc": "description"
}
What am I missing?
Does #equipment.fetch() even trigger a HTTP request?
To my understanding you must set the id: #equipment = new #Equipment(id:123) which would trigger a "/getData/123" request.
or specify the url in the fetch: #equipment.fetch(url:"/getData") to load
But then the view would still be empty, because the data isn't yet loaded when the View render() is executed. Backbone doesn't automatically update views when models change (Like EmberJS does).
Add #listenTo(#model, "change", #render) to the initialize method to re-render when the model changes.
I found a nice guide/tutorial for you
http://adamjspooner.github.com/coffeescript-meet-backbonejs/
You have to tell Backbone to route your initial url ('') like this :
Backbone.history.start pushState: true
You also should pass an id (I think Backbone will request /getData/undefined in your case and on a side note I think you should use coffee's fat arrows instead of bindAll (it's one of the many great thing about coffeescript, but then you should get rid of some of the #s because they won't refer to window anymore...
I would like to know if any better way to create multiple collections fetching from a single big JSON file. I got a JSON file looks like this.
{
"Languages": [...],
"ProductTypes": [...],
"Menus": [...],
"Submenus": [...],
"SampleOne": [...],
"SampleTwo": [...],
"SampleMore": [...]
}
I am using the url/fetch to create each collection for each node of the JSON above.
var source = 'data/sample.json';
Languages.url = source;
Languages.fetch();
ProductTypes.url = source;
ProductTypes.fetch();
Menus.url = source;
Menus.fetch();
Submenus.url = source;
Submenus.fetch();
SampleOne.url = source;
SampleOne.fetch();
SampleTwo.url = source;
SampleTwo.fetch();
SampleMore.url = source;
SampleMore.fetch();
Any better solution for this?
Backbone is great for when your application fits the mold it provides. But don't be afraid to go around it when it makes sense for your application. It's a very small library. Making repetitive and duplicate GET requests just to fit backbone's mold is probably prohibitively inefficient. Check out jQuery.getJSON or your favorite basic AJAX library, paired with some basic metaprogramming as following:
//Put your real collection constructors here. Just examples.
var collections = {
Languages: Backbone.Collection.extend(),
ProductTypes: Backbone.Collection.extend(),
Menus: Backbone.Collection.extend()
};
function fetch() {
$.getJSON("/url/to/your/big.json", {
success: function (response) {
for (var name in collections) {
//Grab the list of raw json objects by name out of the response
//pass it to your collection's constructor
//and store a reference to your now-populated collection instance
//in your collection lookup object
collections[name] = new collections[name](response[name]);
}
}
});
}
fetch();
Once you've called fetch() and the asyn callback has completed, you can do things like collections.Menus.at(0) to get at the loaded model instances.
Your current approach, in addition to being pretty long, risks retrieving the large file multiple times (browser caching won't always work here, especially if the first request hasn't completed by the time you make the next one).
I think the easiest option here is to go with straight jQuery, rather than Backbone, then use .reset() on your collections:
$.get('data/sample.json', function(data) {
Languages.reset(data['Languages']);
ProductTypes.reset(data['ProductTypes']);
// etc
});
If you wanted to cut down on the redundant code, you can put your collections into a namespace like app and then do something like this (though it might be a bit too clever to be legible):
app.Languages = new LanguageCollection();
// etc
$.get('data/sample.json', function(data) {
_(['Languages', 'ProductTypes', ... ]).each(function(collection) {
app[collection].reset(data[collection]);
})
});
I think you can solve your need and still stay into the Backbone paradigm, I think an elegant solution that fits to me is create a Model that fetch the big JSON and uses it to fetch all the Collections in its change event:
var App = Backbone.Model.extend({
url: "http://myserver.com/data/sample.json",
initialize: function( opts ){
this.languages = new Languages();
this.productTypes = new ProductTypes();
// ...
this.on( "change", this.fetchCollections, this );
},
fetchCollections: function(){
this.languages.reset( this.get( "Languages" ) );
this.productTypes.reset( this.get( "ProductTypes" ) );
// ...
}
});
var myApp = new App();
myApp.fetch();
You have access to all your collections through:
myApp.languages
myApp.productTypes
...
You can easily do this with a parse method. Set up a model and create an attribute for each collection. There's nothing saying your model attribute has to be a single piece of data and can't be a collection.
When you run your fetch it will return back the entire response to a parse method that you can override by creating a parse function in your model. Something like:
parse: function(response) {
var myResponse = {};
_.each(response.data, function(value, key) {
myResponse[key] = new Backbone.Collection(value);
}
return myResponse;
}
You could also create new collections at a global level or into some other namespace if you'd rather not have them contained in a model, but that's up to you.
To get them from the model later you'd just have to do something like:
model.get('Languages');
backbone-relational provides a solution within backbone (without using jQuery.getJSON) which might make sense if you're already using it. Short answer at https://stackoverflow.com/a/11095675/70987 which I'd be happy to elaborate on if needed.
What's basic difference between JsonStore and JsonReader in context to Ext.data?
I mean when I should go for JsonStore and when I should use JsonReader as for me both are providing same solution.
Actually they are two separate things. A Ext.data.JsonReader reads a given JSON object and returns data records (Ext.data.Record objects) that are later stored by the respective data store.
The Ext.data.Store is the base class for all Ext storages and uses helper objects for retrieving data (Ext.data.DataProxy), for writing data (Ext.data.DataWriter) and for reading data (Ext.data.DataReader). These base classes come in different flavors such as:
Ext.data.DataProxy:
Ext.data.DirectProxy
Ext.data.HttpProxy
Ext.data.MemoryProxy
Ext.data.ScriptTagProxy
Ext.data.DataWriter
Ext.data.JsonWriter
Ext.data.XmlWriter
Ext.data.DataReader
Ext.data.JsonReader
Ext.data.XmlReader
This all builds up to a very extendable component that allows the developer to configure exactly what he needs to tweak. To make it easier for developers (especially new ones) Ext comes with some pre-configured data stores:
Ext.data.ArrayStore to make reading from simple Javascript arrays easier
Ext.data.DirectStore, just a store preconfigured with an Ext.data.DirectProxy and an Ext.data.JsonReader
Ext.data.JsonStore, just a store preconfigured with an Ext.data.JsonReader
Ext.data.XmlStore, just a store preconfigured with an Ext.data.XmlReader
So actually a Ext.data.JsonStore is just a convenience class to make it easier for the developer.
The following two snippets will create the same (or comparable) stores:
var store = new Ext.data.JsonStore({
url: 'get-images.php',
root: 'images',
idProperty: 'name',
fields: ['name', 'url', {name:'size', type: 'float'}, {name:'lastmod', type:'date'}]
});
// or
var store = new Ext.data.Store({
url: 'get-images.php',
reader: new Ext.data.JsonReader({
root: 'images',
idProperty: 'name',
fields: ['name', 'url', {name:'size', type: 'float'}, {name:'lastmod', type:'date'}]
});
});
A JsonReader reads JSON from a data source into an Ext Store. JsonData is not a specifically-defined Ext object, although maybe you've seen it as a variable name? In what context are you using it?