diff --git a/src/base.ts b/src/base.ts index c9e477f166..96df382913 100644 --- a/src/base.ts +++ b/src/base.ts @@ -101,6 +101,7 @@ export class Base { } private propertyHash = {}; + private arrayOnPush = {}; protected isLoadingFromJsonValue: boolean = false; public onPropertyChanged: Event<(sender: Base, options: any) => any, any> = new Event<(sender: Base, options: any) => any, any>(); /** @@ -131,9 +132,15 @@ export class Base { */ public setPropertyValue(name: string, val: any) { var oldValue = this.propertyHash[name]; - this.propertyHash[name] = val; - if(!this.isTwoValueEquals(oldValue, val)) { - this.propertyValueChanged(name, oldValue, val); + if(oldValue && Array.isArray(oldValue)) { + if(this.isTwoValueEquals(oldValue, val)) return; + this.setArray(oldValue, val, this.arrayOnPush[name]); + this.propertyValueChanged(name, oldValue, oldValue); + } else { + this.propertyHash[name] = val; + if(!this.isTwoValueEquals(oldValue, val)) { + this.propertyValueChanged(name, oldValue, val); + } } } protected propertyValueChanged(name: string, oldValue: any, newValue: any) { @@ -143,6 +150,7 @@ export class Base { protected createNewArray(name: string, onPush: any = null, onRemove: any = null): Array { var newArray = new Array(); this.propertyHash[name] = newArray; + this.arrayOnPush[name] = onPush; var self = this; newArray.push = function (value): number { var result = Array.prototype.push.call(newArray, value); @@ -182,6 +190,13 @@ export class Base { return newArray; } + protected setArray(src: any[], dest: any[], onPush: any) { + src.length = 0; + for(var i = 0; i < dest.length; i ++) { + Array.prototype.push.call(src, dest[i]); + if(onPush) onPush(src[i]); + } + } 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 c6449210f7..758aa0284d 100644 --- a/tests/basetests.ts +++ b/tests/basetests.ts @@ -107,7 +107,7 @@ class BaseTester extends Base { super(); var self = this; this.createNewArray("items", - function(newItem){newItem.owner = self;}, + function(newItem){newItem.isNew = true;}, function(deletedItem){deletedItem.isDeleted = true;}); } public get value1(): number { return this.getPropertyValue("value1"); } @@ -144,15 +144,15 @@ QUnit.test("Base array propety value, push/splice/pop", function (assert) { }); 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(base.items[0].isNew, true, "isNew property is set") 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(base.items[0].isNew, true, "Item1, isNew property is set") + assert.equal(base.items[1].isNew, true, "Item2, isNew property is set") assert.equal(counter, 2, "event called two times"); assert.equal(propertyName, "items", "items has been changed"); @@ -164,3 +164,23 @@ QUnit.test("Base array propety value, push/splice/pop", function (assert) { assert.equal(counter, 4, "event called 4 times, pop is called two times"); assert.equal(propertyName, "items", "items has been changed"); }); +QUnit.test("Base array propety value, set value", function (assert) { + var base = new BaseTester(); + var counter = 0; + var propertyName; + base.onPropertyChanged.add(function (sender, options) { + counter ++; + propertyName = options.name; + }); + base.setPropertyValue("items", [{value1: 1}, {value2: 2}]); + assert.equal(base.items.length, 2, "There are two items"); + assert.equal(base.items[0].isNew, true, "first item, isNew property is set") + assert.equal(base.items[1].isNew, true, "second item, isNew property is set") + assert.equal(counter, 1, "event called one time"); + assert.equal(propertyName, "items", "items has been changed"); + + base.items.push({value: 3}); + assert.equal(base.items.length, 3, "There are 3 items"); + assert.equal(base.items[2].isNew, true, "The third item, isNew property is set") + assert.equal(counter, 2, "event called two time"); +}); \ No newline at end of file