aurelia-templating-binding
Version:
An implementation of the templating engine's Binding Language abstraction which uses a pluggable command syntax.
157 lines (134 loc) • 3.95 kB
text/typescript
import {
connectable,
enqueueBindingConnect,
Expression,
LookupFunctions,
ObserverLocator,
Scope,
sourceContext
} from 'aurelia-binding';
export class LetExpression {
/** @internal */
private observerLocator: ObserverLocator;
/** @internal */
private sourceExpression: Expression;
/** @internal */
private targetProperty: string;
/** @internal */
private lookupFunctions: LookupFunctions;
/** @internal */
private toBindingContext: boolean;
/**
* @param observerLocator
* @param targetProperty
* @param sourceExpression
* @param lookupFunctions
* @param toBindingContext indicates let binding result should be assigned to binding context
*/
constructor(observerLocator: ObserverLocator, targetProperty: string, sourceExpression: Expression, lookupFunctions: LookupFunctions, toBindingContext: boolean) {
this.observerLocator = observerLocator;
this.sourceExpression = sourceExpression;
this.targetProperty = targetProperty;
this.lookupFunctions = lookupFunctions;
this.toBindingContext = toBindingContext;
}
createBinding() {
return new LetBinding(
this.observerLocator,
this.sourceExpression,
this.targetProperty,
this.lookupFunctions,
this.toBindingContext
);
}
}
export class LetBinding {
/** @internal */
private observerLocator: ObserverLocator;
/** @internal */
sourceExpression: Expression;
/** @internal */
private targetProperty: string;
/** @internal */
private lookupFunctions: LookupFunctions;
/** @internal */
source: Scope;
/** @internal */
target: any;
/** @internal */
private toBindingContext: boolean;
/** @internal */
isBound: boolean;
/**
* @param observerLocator
* @param sourceExpression
* @param targetProperty
* @param lookupFunctions
* @param toBindingContext indicates let binding result should be assigned to binding context
*/
constructor(observerLocator: ObserverLocator, sourceExpression: Expression, targetProperty: string, lookupFunctions: LookupFunctions, toBindingContext: boolean) {
this.observerLocator = observerLocator;
this.sourceExpression = sourceExpression;
this.targetProperty = targetProperty;
this.lookupFunctions = lookupFunctions;
this.source = null;
this.target = null;
this.toBindingContext = toBindingContext;
}
updateTarget() {
const value = this.sourceExpression.evaluate(this.source, this.lookupFunctions);
this.target[this.targetProperty] = value;
}
call(context) {
if (!this.isBound) {
return;
}
if (context === sourceContext) {
this.updateTarget();
return;
}
throw new Error(`Unexpected call context ${context}`);
}
/**
* @param {Scope} source Binding context
*/
bind(source) {
if (this.isBound) {
if (this.source === source) {
return;
}
this.unbind();
}
this.isBound = true;
this.source = source;
this.target = this.toBindingContext ? source.bindingContext : source.overrideContext;
if (this.sourceExpression.bind) {
this.sourceExpression.bind(this, source, this.lookupFunctions);
}
enqueueBindingConnect(this);
}
unbind() {
if (!this.isBound) {
return;
}
this.isBound = false;
if (this.sourceExpression.unbind) {
this.sourceExpression.unbind(this, this.source);
}
this.source = null;
this.target = null;
this.unobserve(true);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
unobserve(arg0: boolean) {
throw new Error('Method not implemented.');
}
connect() {
if (!this.isBound) {
return;
}
this.updateTarget();
this.sourceExpression.connect(this, this.source);
}
}