Merge pull request #3958 from NativeScript/property-change-old-value

Property change notifications raise value and oldValue
This commit is contained in:
Panayot Cankov
2017-04-11 10:15:46 +03:00
committed by GitHub
3 changed files with 33 additions and 27 deletions

View File

@ -27,6 +27,10 @@ export interface PropertyChangeData extends EventData {
* The new value of the property. * The new value of the property.
*/ */
value: any; value: any;
/**
* The previous value of the property.
*/
oldValue?: any;
} }
/** /**
@ -129,7 +133,7 @@ export class Observable {
/** /**
* Notifies all the registered listeners for the property change event. * Notifies all the registered listeners for the property change event.
*/ */
notifyPropertyChange(propertyName: string, newValue: any): void; notifyPropertyChange(propertyName: string, value: any, oldValue?: any): void;
/** /**
* Checks whether a listener is registered for the specified event name. * Checks whether a listener is registered for the specified event name.
@ -141,7 +145,7 @@ export class Observable {
/** /**
* This method is intended to be overriden by inheritors to provide additional implementation. * This method is intended to be overriden by inheritors to provide additional implementation.
*/ */
_createPropertyChangeData(name: string, value: any): PropertyChangeData; _createPropertyChangeData(name: string, value: any, oldValue?: any): PropertyChangeData;
_emit(eventNames: string); _emit(eventNames: string);
//@endprivate //@endprivate
} }

View File

@ -40,13 +40,14 @@ export class Observable implements ObservableDefinition {
public set(name: string, value: any) { public set(name: string, value: any) {
// TODO: Parameter validation // TODO: Parameter validation
const oldValue = this[name];
if (this[name] === value) { if (this[name] === value) {
return; return;
} }
const newValue = WrappedValue.unwrap(value); const newValue = WrappedValue.unwrap(value);
this[name] = newValue; this[name] = newValue;
this.notifyPropertyChange(name, newValue); this.notifyPropertyChange(name, newValue, oldValue);
} }
public on(eventNames: string, callback: (data: EventData) => void, thisArg?: any) { public on(eventNames: string, callback: (data: EventData) => void, thisArg?: any) {
@ -125,21 +126,16 @@ export class Observable implements ObservableDefinition {
} }
} }
public notifyPropertyChange(name: string, newValue: any) { public notifyPropertyChange(name: string, value: any, oldValue?: any) {
this.notify(this._createPropertyChangeData(name, newValue)); this.notify(this._createPropertyChangeData(name, value, oldValue));
} }
public hasListeners(eventName: string) { public hasListeners(eventName: string) {
return eventName in this._observers; return eventName in this._observers;
} }
public _createPropertyChangeData(name: string, value: any): PropertyChangeData { public _createPropertyChangeData(propertyName: string, value: any, oldValue?: any): PropertyChangeData {
return { return { eventName: Observable.propertyChangeEvent, object: this, propertyName, value, oldValue };
eventName: Observable.propertyChangeEvent,
propertyName: name,
object: this,
value: value
};
} }
public _emit(eventNames: string) { public _emit(eventNames: string) {
@ -195,7 +191,7 @@ class ObservableFromObject extends Observable {
const newValue = WrappedValue.unwrap(value); const newValue = WrappedValue.unwrap(value);
this._map[name] = newValue; this._map[name] = newValue;
this.notifyPropertyChange(name, newValue); this.notifyPropertyChange(name, newValue, currentValue);
} }
} }

View File

@ -3,7 +3,7 @@ import * as definitions from "../view-base";
import { ViewBase } from "../view-base"; import { ViewBase } from "../view-base";
// Types. // Types.
import { WrappedValue } from "../../../data/observable"; import { WrappedValue, PropertyChangeData } from "../../../data/observable";
import { Style } from "../../styling/style"; import { Style } from "../../styling/style";
export { Style }; export { Style };
@ -131,11 +131,12 @@ export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<
} }
if (this.hasListeners(eventName)) { if (this.hasListeners(eventName)) {
this.notify({ this.notify<PropertyChangeData>({
eventName: eventName, eventName: eventName,
propertyName: name, propertyName: name,
object: this, object: this,
value: unboxedValue value: unboxedValue,
oldValue: currentValue
}); });
} }
@ -163,11 +164,12 @@ export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<
} }
if (owner.hasListeners(eventName)) { if (owner.hasListeners(eventName)) {
owner.notify({ owner.notify<PropertyChangeData>({
eventName: eventName, eventName: eventName,
propertyName: name, propertyName: name,
object: owner, object: owner,
value: value value: value,
oldValue: currentValue
}); });
} }
@ -275,11 +277,12 @@ export class CoercibleProperty<T extends ViewBase, U> extends Property<T, U> imp
} }
if (this.hasListeners(eventName)) { if (this.hasListeners(eventName)) {
this.notify({ this.notify<PropertyChangeData>({
eventName: eventName, eventName: eventName,
propertyName: name, propertyName: name,
object: this, object: this,
value: unboxedValue value: unboxedValue,
oldValue: currentValue
}); });
} }
@ -460,11 +463,12 @@ export class CssProperty<T extends Style, U> implements definitions.CssProperty<
} }
if (this.hasListeners(eventName)) { if (this.hasListeners(eventName)) {
this.notify({ this.notify<PropertyChangeData>({
eventName: eventName, eventName: eventName,
propertyName: name, propertyName: name,
object: this, object: this,
value: value value: value,
oldValue: currentValue
}); });
} }
@ -529,11 +533,12 @@ export class CssProperty<T extends Style, U> implements definitions.CssProperty<
} }
if (this.hasListeners(eventName)) { if (this.hasListeners(eventName)) {
this.notify({ this.notify<PropertyChangeData>({
eventName: eventName, eventName: eventName,
propertyName: name, propertyName: name,
object: this, object: this,
value: value value: value,
oldValue: currentValue
}); });
} }
@ -676,7 +681,7 @@ export class CssAnimationProperty<T extends Style, U> {
this.view[setNative](next); this.view[setNative](next);
} }
if (this.hasListeners(eventName)) { if (this.hasListeners(eventName)) {
this.notify({ eventName, object: this, propertyName, value }); this.notify<PropertyChangeData>({ eventName, object: this, propertyName, value, oldValue: prev });
} }
} }
} }
@ -812,11 +817,12 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
} }
if (this.hasListeners(eventName)) { if (this.hasListeners(eventName)) {
this.notify({ this.notify<PropertyChangeData>({
eventName: eventName, eventName: eventName,
propertyName: name, propertyName: name,
object: this, object: this,
value: newValue value: newValue,
oldValue: currentValue
}); });
} }