Dynamic binding expression

cc @AshleyGrant
I have just read Ashely’s post.

I can do it in simpler alternative way, without deep understanding of aurelia-binding.

My approach is to use value converter, not binding behavior. The result is human understandable code, plus more permissive in chain of value converters.

Note: beware the fromView expects a simple propertyExpression like "address.city", otherwise the setExp will fail. But this doesn’t mean GetValueConverter cannot be used for complex expression like "address.state + ' ' + address.zip". You can still use GetValueConverter in one-way binding with complex expression, where fromView is never called.

Update: thx for @bigopon’s help, it now works correctly if used in more than 1 place.


@inject(Parser)
export class GetValueConverter {
    constructor(parser) {
     this.parser = parser;
    }
    
    toView(_: any, model: any, propertyExpression: string): any {
        let getExp = this.parser.parse(propertyExpression);
        return getExp.evaluate({ bindingContext: model });
    }
    
    fromView(value: any, model: any, propertyExpression: string): any {
        let setExp = this.parser.parse(propertyExpression + ' = $value');
        setExp.evaluate({
          bindingContext: model,
          overrideContext: { $value: value }
        });
        
        return model;
    }
}

The downside is the binding is now verbose, you have to call model twice in order to pass enough information to the value converter.

<input value.bind="model | get:model:property.expression | localDebug">

See it working here:

2 Likes