File

projects/wms-framework/src/lib/basecomponentmodel/Bindings/BindingExpression.ts

Description

Class for represting binding expression of a specific property

Index

Properties
Methods
Accessors

Constructor

constructor(element: DependencyObject, parentBinding: Binding)

Creates an instance of BindingExpression.

Parameters :
Name Type Optional
element DependencyObject No
parentBinding Binding No

Properties

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

Methods

Public AddRelatedSubscription
AddRelatedSubscription(eventToUnsubscribe: SubscriptionEvent<any>, subscription: any)

Add a subscription to the pending subscriptions to cleanup

Parameters :
Name Type Optional
eventToUnsubscribe SubscriptionEvent<any> No
subscription any No
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 :
Name Type Optional
object DependencyObject No
dependencyProperty DependencyProperty No
Returns : void
Public OnDetach
OnDetach(object: DependencyObject, dependencyProperty: DependencyProperty)

On detach binding expression

Parameters :
Name Type Optional
object DependencyObject No
dependencyProperty DependencyProperty No
Returns : void
Private TargetLostFocus
TargetLostFocus(sender: any, e: any)

Executes the target object binding update value when lost focus the TargetFE.

Parameters :
Name Type Optional
sender any No
e any No
Returns : void
Public UpdateSource
UpdateSource()

Updates the source of a two way binding

Returns : void

Accessors

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);
    }
  }
}

result-matching ""

    No results matching ""