diff --git a/src/base.ts b/src/base.ts index 406ebaabe0..c9e477f166 100644 --- a/src/base.ts +++ b/src/base.ts @@ -119,7 +119,16 @@ export class Base { endLoadingFromJson() { this.isLoadingFromJsonValue = false; } + /** + * Returns the property value by name + * @param name property name + */ public getPropertyValue(name: string): any { return this.propertyHash[name]; } + /** + * set property value + * @param name property name + * @param val new property value + */ public setPropertyValue(name: string, val: any) { var oldValue = this.propertyHash[name]; this.propertyHash[name] = val; @@ -131,6 +140,48 @@ export class Base { if(this.isLoadingFromJson) return; this.onPropertyChanged.fire(this, {name: name, oldValue: oldValue, newValue: newValue}); } + protected createNewArray(name: string, onPush: any = null, onRemove: any = null): Array { + var newArray = new Array(); + this.propertyHash[name] = newArray; + var self = this; + newArray.push = function (value): number { + var result = Array.prototype.push.call(newArray, value); + if(onPush) onPush(value); + self.propertyValueChanged(name, newArray, newArray); + return result; + }; + newArray.pop = function (): number { + var result = Array.prototype.pop.call(newArray); + if(onRemove) onRemove(result); + self.propertyValueChanged(name, newArray, newArray); + return result; + }; + newArray.splice = function (start?: number, deleteCount?: number, ...items: any[]): any[] { + if(!start) start = 0; + if(!deleteCount) deleteCount = 0; + var deletedItems = []; + for(var i = 0; i < deleteCount; i ++) { + if(i + start >= newArray.length) continue; + deletedItems.push(newArray[i + start]); + } + var result = Array.prototype.splice.call(newArray, start, deleteCount, ... items); + if(!items) items = []; + if(onRemove) { + for(var i = 0; i < deletedItems.length; i ++) { + onRemove(deletedItems[i]) + } + } + if(onPush) { + for(var i = 0; i < items.length; i ++) { + onPush(items[i], start + i); + } + } + self.propertyValueChanged(name, newArray, newArray); + return result; + }; + + return newArray; + } protected isTwoValueEquals(x: any, y: any): boolean { if (x === y) return true; if (!(x instanceof Object) || !(y instanceof Object)) return false; diff --git a/tests/basetests.ts b/tests/basetests.ts index 6bff7aefeb..c6449210f7 100644 --- a/tests/basetests.ts +++ b/tests/basetests.ts @@ -103,11 +103,19 @@ QUnit.test("ItemValue.getItemByValue()", function (assert) { }); class BaseTester extends Base { + constructor() { + super(); + var self = this; + this.createNewArray("items", + function(newItem){newItem.owner = self;}, + function(deletedItem){deletedItem.isDeleted = true;}); + } public get value1(): number { return this.getPropertyValue("value1"); } public set value1(val: number) { this.setPropertyValue("value1", val); } + public get items(): Array { return this.getPropertyValue("items"); } } -QUnit.test("Base changed value", function (assert) { +QUnit.test("Base simple propety value", function (assert) { var base = new BaseTester(); var counter = 0; var propertyName; @@ -125,3 +133,34 @@ QUnit.test("Base changed value", function (assert) { assert.notOk(oldValue, "oldValue is underfined"); assert.equal(newValue, 5, "newValue is 5"); }); + +QUnit.test("Base array propety value, push/splice/pop", function (assert) { + var base = new BaseTester(); + var counter = 0; + var propertyName; + base.onPropertyChanged.add(function (sender, options) { + counter ++; + propertyName = options.name; + }); + base.items.push({value: 1}); + assert.equal(base.items.length, 1, "There is one item"); + assert.equal(base.items[0].owner, base, "Owner property is set to base") + assert.equal(counter, 1, "event called one time"); + assert.equal(propertyName, "items", "items has been changed"); + var item = base.items[0]; + base.items.splice(0, 1, {value: 2}, {value: 3}); + assert.equal(base.items.length, 2, "There are two items"); + assert.equal(item.isDeleted, true, "First Item is deleted") + assert.equal(base.items[0].owner, base, "Item1, Owner property is set to base") + assert.equal(base.items[0].owner, base, "Item2, Owner property is set to base") + assert.equal(counter, 2, "event called two times"); + assert.equal(propertyName, "items", "items has been changed"); + + item = base.items[0]; + base.items.pop(); + base.items.pop(); + assert.equal(base.items.length, 0, "There is no items"); + assert.equal(item.isDeleted, true, "Item is deleted") + assert.equal(counter, 4, "event called 4 times, pop is called two times"); + assert.equal(propertyName, "items", "items has been changed"); +});