projects/wms-framework/src/lib/basecomponentmodel/Bindings/BindingExpression.ts
Class for represting binding expression of a specific property
Properties |
|
Methods |
|
Accessors |
constructor(element: DependencyObject, parentBinding: Binding)
|
|||||||||
Creates an instance of BindingExpression.
Parameters :
|
Private inInvalidState |
Type : boolean
|
Default value : false
|
Flag to indicate the binding expression is in an invalid state, like when all subscriptions have been removed but the expression|model haven't been destroyed, code should reconsider re-create the expression again. Subscriptions can be removed when the angular component is destroyed, yet the model can persist, like when a parent component has an *ngIf that removes the component from the DOM, yet the model should persist because the *ngIf corresponds to a temporal condition, like visibility=false |
isDirty |
Type : boolean
|
Default value : false
|
Flags which indicates that the target dependency property has changed and its pending to be updated |
Public listenToLostFocus |
Default value : false
|
Indicates if the binding is listening to the lost focus to update the binding |
Private property |
Type : DependencyProperty
|
Default value : null
|
The property associated to the binding expression |
Public subscriptions |
Type : Array<>
|
Default value : []
|
List of subscriptions used by this binding This is used to clean up these subscriptions in the future |
TargetFE |
Type : any
|
Default value : null
|
The target framework element where the binding was attach |
Public updateSourceFunction |
Type : function
|
Default value : null
|
Function used to update the source of the binding |
Public AddRelatedSubscription | |||||||||
AddRelatedSubscription(eventToUnsubscribe: SubscriptionEvent<any>, subscription: any)
|
|||||||||
Add a subscription to the pending subscriptions to cleanup
Parameters :
Returns :
void
|
Public CleanupSubscriptions |
CleanupSubscriptions()
|
Remove all subscriptions related to this binding
Returns :
void
|
Public IsTargetFocused |
IsTargetFocused()
|
Returns true if the target control has the focus
Returns :
boolean
|
Public OnAttach | |||||||||
OnAttach(object: DependencyObject, dependencyProperty: DependencyProperty)
|
|||||||||
On atach binding expression
Parameters :
Returns :
void
|
Public OnDetach | |||||||||
OnDetach(object: DependencyObject, dependencyProperty: DependencyProperty)
|
|||||||||
On detach binding expression
Parameters :
Returns :
void
|
Private TargetLostFocus |
TargetLostFocus(sender: any, e: any)
|
Executes the target object binding update value when lost focus the TargetFE.
Returns :
void
|
Public UpdateSource |
UpdateSource()
|
Updates the source of a two way binding
Returns :
void
|
Property |
getProperty()
|
The property associated to the binding expression
Returns :
DependencyProperty
|
InInvalidState |
getInInvalidState()
|
Flag to indicate the binding expression is in an invalid state, like when all subscriptions have been removed but the expression|model haven't been destroyed, code should reconsider re-create the expression again. Subscriptions can be removed when the angular component is destroyed, yet the model can persist, like when a parent component has an *ngIf that removes the component from the DOM, yet the model should persist because the *ngIf corresponds to a temporal condition, like visibility=false Hint, if this flag is on then probably there is something wrong with the expression and should be re-created
Returns :
boolean
|
ParentBinding |
getParentBinding()
|
The parent binding definition
Returns :
Binding
|
DataItem |
getDataItem()
|
Gets the data item
Returns :
any
|
import { Debugger } from '../../diagnostics/Debugger';
import { AngularComponentId } from '../../helpers/AngularComponentId';
import { SubscriptionEvent } from '../../utils/SubscriptionEvent';
import { DependencyObject } from '../DependencyObject';
import {
DependencyProperty,
FocusCoreDependencyProperty,
} from '../DependencyProperty';
import { Binding } from './Binding';
import { BindingMode } from './BindingMode';
/**
* Class for represting binding expression of a specific property
*
* @export
* @class BindingExpression
* @wType System.Windows.Data.BindingExpression
*/
export class BindingExpression {
/**
* Flag to indicate the binding expression is in an invalid state, like when all subscriptions have been removed but the expression|model
* haven't been destroyed, code should reconsider re-create the expression again.
*
* Subscriptions can be removed when the angular component is destroyed, yet the model can persist, like when a parent component has an *ngIf that
* removes the component from the DOM, yet the model should persist because the *ngIf corresponds to a temporal condition, like visibility=false
*
* @private
* @type {boolean}
* @memberof BindingExpression
*/
private inInvalidState: boolean = false;
/**
* Indicates if the binding is listening to the lost focus to update the binding
*
* @private
* @memberof BindingExpression
*/
public listenToLostFocus = false;
/**
* Function used to update the source of the binding
*
* @memberof BindingExpression
*/
public updateSourceFunction: () => void = null;
/**
* The target framework element where the binding was attach
*
* @type {*}
* @memberof Binding
* @wIgnore
*/
TargetFE: any = null;
/**
* List of subscriptions used by this binding
* This is used to clean up these subscriptions in the future
*
* @type {Array<[SubscriptionEvent<any>, any]>}
* @memberof BindingExpression
*/
public subscriptions: Array<[SubscriptionEvent<any>, any]> = [];
/**
* The property associated to the binding expression
*
* @type {DependencyProperty}
* @memberof BindingExpression
*/
private property: DependencyProperty = null;
/**
* Flags which indicates that the target dependency property has changed and its pending to be updated
*
* @type {boolean}
* @memberof BindingExpression
*/
isDirty: boolean = false;
/**
* Creates an instance of BindingExpression.
* @param {DependencyObject} element
* @param {Binding} parentBinding
* @memberof BindingExpression
*/
constructor(
private element: DependencyObject,
private parentBinding: Binding
) {}
/**
* The property associated to the binding expression
*
* @readonly
* @type {DependencyProperty}
* @memberof BindingExpression
* @wIgnore
*/
public get Property(): DependencyProperty {
return this.property;
}
/**
* Flag to indicate the binding expression is in an invalid state, like when all subscriptions have been removed but the expression|model
* haven't been destroyed, code should reconsider re-create the expression again.
*
* Subscriptions can be removed when the angular component is destroyed, yet the model can persist, like when a parent component has an *ngIf that
* removes the component from the DOM, yet the model should persist because the *ngIf corresponds to a temporal condition, like visibility=false
*
* Hint, if this flag is on then probably there is something wrong with the expression and should be re-created
*
* @readonly
* @type {boolean}
* @memberof BindingExpression
* @wIgnore
*/
public get InInvalidState(): boolean {
return this.inInvalidState;
}
/**
* The parent binding definition
*
* @readonly
* @type {Binding}
* @memberof BindingExpression
*/
public get ParentBinding(): Binding {
return this.parentBinding;
}
/**
* Gets the data item
*
* @readonly
* @type {*}
* @memberof BindingExpression
* @wNoMap
*/
public get DataItem(): any {
Debugger.Throw('Not implemented');
return null;
}
/**
* Updates the source of a two way binding
*
* @memberof BindingExpression
*/
public UpdateSource() {
if (this.updateSourceFunction) {
this.updateSourceFunction();
}
}
/**
* Add a subscription to the pending subscriptions to cleanup
*
* @param {SubscriptionEvent<any>} eventToUnsubscribe
* @param {*} subscription
* @memberof BindingExpression
* @wIgnore
*/
public AddRelatedSubscription(
eventToUnsubscribe: SubscriptionEvent<any>,
subscription: any
) {
this.subscriptions.push([eventToUnsubscribe, subscription]);
}
/**
* Remove all subscriptions related to this binding
*
* @memberof BindingExpression
* @wIgnore
*/
public CleanupSubscriptions() {
for (const subscription of this.subscriptions) {
subscription[0].removeHandler(subscription[1]);
this.inInvalidState = true;
}
this.subscriptions = [];
}
/**
* On atach binding expression
*
* @param {DependencyObject} object
* @param {DependencyProperty} dependencyProperty
* @memberof BindingExpression
* @wIgnore
*/
public OnAttach(
object: DependencyObject,
dependencyProperty: DependencyProperty
) {
this.property = dependencyProperty;
this.TargetFE = object;
if (
this.parentBinding.Mode === BindingMode.TwoWay &&
dependencyProperty instanceof FocusCoreDependencyProperty
) {
this.listenToLostFocus = true;
this.TargetFE.LostFocus.addHandler(this.TargetLostFocus, this);
}
}
/**
* On detach binding expression
*
* @param {DependencyObject} object
* @param {DependencyProperty} dependencyProperty
* @memberof BindingExpression
* @wIgnore
*/
public OnDetach(
object: DependencyObject,
dependencyProperty: DependencyProperty
) {
this.CleanupSubscriptions();
if (this.TargetFE && this.listenToLostFocus) {
this.TargetFE.LostFocus.removeHandler(this.TargetLostFocus, this);
}
this.property = null;
this.TargetFE = null;
}
/**
* Returns true if the target control has the focus
*
* @memberof BindingExpression
* @wIgnore
*/
public IsTargetFocused(): boolean {
return this.TargetFE?.hasFocus;
}
/**
* Executes the target object binding update value when lost focus the TargetFE.
*
* @private
* @param {*} sender
* @param {*} e
* @memberof BindingExpression
*/
private TargetLostFocus(sender: any, e: any) {
const textBoxTarget =
this.TargetFE.AngularComponentId === AngularComponentId.textBox ||
(this.property instanceof FocusCoreDependencyProperty &&
this.TargetFE &&
'dirtyInput' in this.TargetFE);
if (
(textBoxTarget && this.TargetFE.dirtyInput && this.isDirty) ||
(!textBoxTarget && this.isDirty)
) {
this.UpdateSource();
textBoxTarget && (this.TargetFE.dirtyInput = false);
}
}
}