You will need copies of the following files:
We already know that object literals can be written as:
var literalObj = {
someText: "Hello World",
someNumber: 10
};JSON also provides data in a similar form, so converting this object to JSON is straightforward, in jQuery it looks like this:var json = JSON.stringify(literalObj);
The objective is to build a class that contains an object literal and provides methods to read and write data to it. When you create a model using this class, you define the data fields that are associated with the model by passing an object literal in the constructor together with the name of the primary key.
var dataFields: Object;
var primaryKeyName: string;
var model: Model;
primaryKeyName = "id";
dataFields = { id: 0, name: "Fred"}
// Pass the data structure to define the data fields
// the Model should use and the name of primary key field
model = new Model(dataFields, primaryKeyName);
The model should ensure that only the data fields specified this way can be used by providing a SetData() and GetData() that will only set or get values for the data fields specified in the constructor. Extending the previous example, we can only set or get the "id" and "name" values.
var model: Model = new Model({ id: 0, name: "Fred"}, "id");
var id: number;
var name: string;
model.SetData("id", 2);
model.SetData("name", "Fred");
id = model.GetData("id"); ← result is 2
name = model.GetData("name"); ← result is "Fred"The class will also provide methods for converting the object into HTML pairs or JSON format.class Model
{
// Attributes
private _data: Object; ← This is the object literal
private _primaryKeyName: string = "id";
private _primaryKeySet: boolean = false;
// Constructor
constructor(dataFields: any, primaryKeyName: string)
{
this._data = dataFields; ← Here we store the object
this._primaryKeyName = primaryKeyName;
};
Line 4 shows the attribute that will contain the object literal and at line 11 the attribute is set by passing an object literal into the constructor.
When setting the values would like to be able to use a method SetData() that checks that the property name is valid (and in a later exercise we also want to check that the value provided is the correct type). Any attempt to set a property that does not exist should be ignored, or you may choose to return a boolean if you wish.
var myData: Model = new Model();
var propertyName: string = "name";
var name: string = "Fred";
myData.SetData(propertyName, name);
// Or set value this way
model.SetData("age", 22);
We will also need a method GetData() to read a stored value. Any attempt to use a property that doesn't exist should result in undefined being returned.
var myData: Model = new Model();
var propertyName: string = "name";
var name: string;
name = myData.GetData(propertyName);
if(name !== undefined) window.alert("Name is " + name);
// Or read value this way
var age: number;
age = myData.GetData("age");
// Attempt to read non-existant field results in undefined being returned
age = myData.GetData("non-existant-field-name");
if(age === undefined) window.alert("Data field does not exist");
The methods should look like this:
SetData(fieldName: string, value: any): boolean
{
// Your code here
}
GetData(fieldName: string): any
{
// Your code here
}
Finally, the class must handle the primary key slightly differently. The class will need to told the primary key name and if the key value is not set then the GetData() method must return undefined.
var myData: Model = new Model("id");
var keyName: string = "id";
var keyValue: number;
// Key not set so undefined returned
keyValue = myData.GetData(keyName);
if(keyValue === undefined) window.alert("Key value not set yet");
// Set the key value
keyValue = 2;
myData.SetData(keyName, keyValue);
// Key value set, so value is returned
keyValue = myData.GetData(keyName);
if(keyValue !== undefined) window.alert("Key value is " + keyValue);
HTML
To convert the data in the wrapped object to name/value pairs try including the HTMLPairsConvertor.ts file and adding the following method to the Model class:
ToHTMLPairs(skipList?: string[]): string
{
return HTMLPairsConvertor.ConvertObjToPairs(this._data, skipList);
}
The skipList is optional and is used when you wish to prevent properties from being converted to pairs. For now you can ignore this argument when you test this method.
You might use it like this:
var myData: Model = new Model();
var pairs: string;
model.SetData("name", "Fred");
model.SetData("age", 22);
pairs = model.ToHTMLPairs(); ← name=Fred&age=22
var obj: Object = { age: 12 };
var propName: string = "age";
// These three lines are all equivalent
obj.age = 3;
obj["age"] = 3;
obj[propName] = 3; // Use a variabel propName to select the property value to set
// Use within a method
ChangeValue(propName: string, value: any) : void
{
// Assumes the property exists and is not undefined.
this._data[propName] = value;
}
var propertyName: string = "name";
if(this._data[propertyName] !== undefined)
{
// The data field exists
}