I have a column model like that:
...
{name:'password',index:'password', width:100},
{name:'type.name',index:'type.name', width:100},
...
My class like definitons:
var MyObject = function (password, type) {
this.password = password;
this.type = type;
};
var MyType = function (tname) {
this.tname = tname;
};
I populate my variables: like that:
var type = new MyType($('#typeList').val());
var myObject = new MyObject($('#password').val(), type);
I have a JSON data response from my server and some of it's elements are object as like type. When I want to show them at my grid its OK. However when I want to use addrowdata function I can not see anything at type column. I am doing like that:
$("#gridId").jqGrid('addRowData', myObject.password, myObject, "first");
class is the function that hold name, password etc. inside it. The problem is only with nested elements(I can see password etc. at my grid). addrowData fonction accepts an array but I send a abject that holds object. How can I convert my object of objects into a plaint object array?
Any ideas?
You should not use points in the name property! If needed you can use if in index or in jsonmap.
The usage of addRowData in your example seems me wrong. You should reread the documentation of addRowData method.
Related
In Python, I can create objects from JSON pretty easily. I can either populate classes or just create a generic object. I see that Chapel has a read method for JSON, but I'm not sure how to use it.
If I have:
class Fighter {
var subclass:string;
var level:int;
}
and a string:
s = "{'subclass':'Ninja', 'level':7}"
How do I get a Fighter object?
And are there methods like:
n = json.loads(s)
n['subclass'] # = 'ninja', but just as a field key
Or:
Hattori = Fighter.read(s);
Hattori['subclass'] # = 'ninja'
Thanks!
It would be possible to make something like json.loads(s) work by creating some particular type (e.g. JSONNode) and populating it.
However right now we can get something in your example to work:
class Fighter {
var subclass:string;
var level:int;
}
var mem = openmem();
var writer = mem.writer().write('{"subclass":"ninja", "level":7}');
var reader = mem.reader();
var f = new Fighter();
reader.readf("%jt", f);
writeln(f);
Note that the class instance currently has to be allocated before you read it. Or you can use a record, for which there isn't a nil value.
Say I have a class Person with a private array called children, containing Person objects. It has a method getChildren():Array { return this.children; }.
If I do trace(p.getChildren()[0]) (where p is an instance of Person), I can successfully print out whatever the first child is in the array. However, if I try to cast var firstChild:Person = p.getChildren()[0], I get an error saying Type Coercion failed: cannot convert []#a027b81 to classes.Person.
What is going wrong?
When you do: var firstChild:Person = p.getChildren()[0] your not actually casting. Your just trying to stuff an Array into an object you've defined as a Person and that's why you receive the error.
To cast, you need to do one of the following:
var firstChild:Person = Person(p.getChildren()[0]); //this will error if the cast fails
var firstChild:Person = p.getChildren()[0] as Person; //this will return null if the cast fails
A better approach however, may be to use a Vector - which in AS3 is like an array but all the members have to be of the specified type. So something like this:
private var children_:Vector.<Person>;
public function getChildren():Vector.<Person>{ return this.children_; }
Then you could just do:
var firstChild:Person = p.getChildren()[0]
Because each member of the Vector is already defined as a Person object.
Also, you may want to consider using a getter method instead of getChildren.
public function get children():Vector.<Person> { return this.children_;}
Then you access it like a property (but can't set it).
I am trying to map various markers on google map with a info window. It is all working fine till I try to pass a string through the controller.
I get the error below:
"LINQ to Entities does not recognize the method 'System.String GetMainPhoto(Int32)' method, and this method cannot be translated into a store expression."
I have read this is mainly caused because ToString method or some other methods are not valid to use. But, I am not really sure how to correct this error in this case.
Basically, I have a db - PropertyPhoto that holds the filename of the pictures. GetMainPhoto basically looks up all the rows and returns the main pic file name.
public string GetMainPhoto(int id)
{
return db.PropertyPhotos.Single(p => p.PropertyId == id && p.MainPic == true).PhotoLocation;
}
Controller is as follows:
public ActionResult Map()
{
if (Request.IsAjaxRequest())
{
var properties = websiteRepository.FindAllProperties();
var jsonProperties = from property in properties
select new JsonProperty
{
PropertyId = property.PropertyId,
NoOfBedroom = property.NoOfBedrooms,
Price = property.Price,
Address1 = property.PropertyAddress.Address1,
MainPicSrc = websiteRepository.GetMainPhoto(property.PropertyId),
Latitude = property.PropertyAddress.Latitude,
Longitude = property.PropertyAddress.Longitude
};
return Json(jsonProperties.ToList(), JsonRequestBehavior.AllowGet);
}
else
{
return View();
}
}
Try to eagerly load the data first by calling .ToList() before projecting into an anonymous type, otherwise EF doesn't know how to translate the websiteRepository.GetMainPhoto call to SQL:
var properties = websiteRepository.FindAllProperties().ToList();
Be careful though. By doing this you might be experiencing the SELECT N+1 problem because for each element of the initial resultset you will be sending a SQL query to fetch the MainPicSrc property.
A better approach would be to perform this join directly by the database and don't use the websiteRepository.GetMainPhoto call.
I am trying to have a more dynamic function and would like to allow the functions instance name were it outputs the text to be changeable.
for example
function example_function(url,instance_name){
instance_name.text = url;
}
example_function('www.example.com','url_txt');
example_function('www.another.com','more_txt');
Is this possible?
Yes, just parse the string into square brackets next to the instance's owner. For example:
this[instance_name].text = url;
More info:
Take this object:
var obj:Object = {
property1: 10,
property2: "hello"
};
Its properties can be accessed either as you'd expect:
obj.property1;
obj.property2;
Or as mentioned above:
obj["property1"];
obj["property2"];
I suggest using a function like this one I've created to tighten your code up a bit:
function selectProperty(owner:*, property:String):*
{
if(owner.hasOwnProperty(property)) return owner[property];
else throw new Error(owner + " does not have a property \"" + property + "\".");
return null;
}
trace(selectProperty(stage, "x")); // 0
trace(selectProperty(stage, "test")); // error
It is definitely possible, but it's not really best practice to do it with Strings like that. Instead, you can pass in a reference to the variable you're trying to modify.
function example_function(url : String, instance : TextField) : void {
instance.text = url;
}
example_function("www.example.com", url_txt);
This gives you strong typing so you can tell at compile time if you're operating on a TextField or not. If you aren't, you'll get an error because the 'text' property doesn't exist. You'll be able to find and track down errors faster this way.
However, if you must do it with Strings, you can access any property on any object using a string key like:
var myInstance = this[instance_name]
So in your example, you could do:
function example_function(url : String, instance : TextField) : void {
this[instance_name].text = url;
}
example_function("www.example.com", "url_txt");
How can I achieve the following for any number of elements in the arg array? If it was a function, I'd use Function.apply(), but I can't figure out how to do it with the new operator.
var arg:Array = [1,2];
new MyClass( arg[0], arg[1] );
If you set up your class to accept a list of arguments using ... args you can pass in as many as you like. Then in the constructor you will access them just like a normal array.
class MyClass
{
public function MyClass(... args):void
{
//args is an Array containing all the properties sent to the constructor
trace(args.length);
}
}
Dont pass each element of the array, just pass the array.
var arg:Array = [1,2];
new MyClass(arg);
Then inside of your class, loop through the array.
It is unfortunately not possible, because there is no way to directly access the constructor method of a Class object.
Note: If you'd be using a Function object to make up your class (prototype inheritance), then it would be possible, but i figure, this is not an option for you.
You could work around the problem with a little (ugly) helper method, on which you can read about here: http://jacksondunstan.com/articles/398
As stated in the comments is is not possible to apply settings on the constructor, but you could use this trick to set properties on a new instance of a class (which should be public)
public function setProps(o:Object, props:Object):* {
for (var n:String in props) {
o[n] = props[n];
}
return o;
}
.. use it like this
var args:Object = {x:1, y:2};
var instance:MyClass = setProps( new MyClass(), args ) );
source:
http://gskinner.com/blog/archives/2010/05/quick_way_to_se.html