Created
April 19, 2016 09:17
-
-
Save lynsei/7dbeb839e2eeef7d0b68d1cc5655863f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<require from="./dynamic-expression-binding-behavior"></require> | |
<require from="./debug"></require> | |
<label> | |
Address 1: | |
<input value.bind="model & dynamicExpression:'address.address1'"> | |
</label> | |
<label> | |
Address 2: | |
<input value.bind="model & dynamicExpression:'address.address2'"> | |
</label> | |
<label> | |
City: | |
<input value.bind="model & dynamicExpression:key"> | |
</label> | |
<label> | |
State: | |
<input value.bind="model & dynamicExpression:'address.state'"> | |
</label> | |
<label> | |
Zip: | |
<input value.bind="model & dynamicExpression:'address.zip'"> | |
</label> | |
<label> | |
Address 1: | |
<input value.bind="model & dynamicExpression:'address.address1'"> | |
</label> | |
<label> | |
Address 2: | |
<input value.bind="model & dynamicExpression:'address.address2'"> | |
</label> | |
<label> | |
City: | |
<input value.bind="model & dynamicExpression:key"> | |
</label> | |
<label> | |
State: | |
<input value.bind="model & dynamicExpression:'address.state'"> | |
</label> | |
<label> | |
Zip: | |
<input value.bind="model & dynamicExpression:'address.zip'"> | |
</label> | |
<debug></debug> | |
</template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class App { | |
model = { | |
address: { | |
address1: '1 Main Street', | |
address2: '', | |
city: 'Burlington', | |
state: 'VT', | |
zip: '05401' | |
} | |
}; | |
key = 'address.city'; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<pre><code>${json}</code></pre> | |
</template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class Debug { | |
bindingContext = null; | |
updateJson() { | |
if (this.bindingContext === null) { | |
this.json = 'null'; | |
} else if (this.bindingContext === undefined) { | |
this.json = 'undefined' | |
} else { | |
// todo: use a stringify function that can handle circular references. | |
this.json = JSON.stringify(this.bindingContext, null, 2); | |
} | |
} | |
bind(bindingContext) { | |
this.bindingContext = bindingContext; | |
this.updateJson(); | |
this.interval = setInterval(::this.updateJson, 150); | |
} | |
unbind() { | |
this.bindingContext = null; | |
clearInterval(this.interval); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {inject} from 'aurelia-dependency-injection'; | |
import {Parser} from 'aurelia-binding'; | |
import './temporary-fix-for-binding'; | |
@inject(Parser) | |
export class DynamicExpressionBindingBehavior { | |
constructor(parser) { | |
this.parser = parser; | |
} | |
bind(binding, source, rawExpression) { | |
// Quick and dirty expression concatenation. A more robust way to do this is | |
// with a visitor, but this is good enough for the OP's use case. | |
// When I get some time I will update this with an expression visitor. | |
let combinedRawExpression = binding.sourceExpression.expression.toString() + '.' + rawExpression; | |
// parse the combined concatenated expression. | |
let expression = this.parser.parse(combinedRawExpression); | |
// replace the binding's expression. | |
binding.replaceSourceExpression(expression); | |
} | |
unbind(binding, source) { | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title>Aurelia</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<style> | |
label, input { | |
display: block; | |
} | |
</style> | |
</head> | |
<body aurelia-app> | |
<h1>Loading...</h1> | |
<script src="https://cdn.rawgit.com/jdanyow/aurelia-bundle/v1.0.3/jspm_packages/system.js"></script> | |
<script src="https://cdn.rawgit.com/jdanyow/aurelia-bundle/v1.0.3/config.js"></script> | |
<script> | |
System.import('aurelia-bootstrapper'); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Binding, bindingMode} from 'aurelia-binding'; | |
// monkey patch the Binding class to enable | |
// binding behaviors to entirely replace the sourceExpression | |
const targetContext = 'Binding:target'; | |
Binding.prototype.bind = function(source) { | |
if (this.isBound) { | |
if (this.source === source) { | |
return; | |
} | |
this.unbind(); | |
} | |
this.isBound = true; | |
this.source = source; | |
let sourceExpression = this.sourceExpression; | |
if (sourceExpression.bind) { | |
sourceExpression.bind(this, source, this.lookupFunctions); | |
sourceExpression = this.sourceExpression; | |
} | |
let mode = this.mode; | |
if (!this.targetObserver) { | |
let method = mode === bindingMode.twoWay ? 'getObserver' : 'getAccessor'; | |
this.targetObserver = this.observerLocator[method](this.target, this.targetProperty); | |
} | |
if ('bind' in this.targetObserver) { | |
this.targetObserver.bind(); | |
} | |
let value = sourceExpression.evaluate(source, this.lookupFunctions); | |
this.updateTarget(value); | |
if (mode === bindingMode.oneWay) { | |
enqueueBindingConnect(this); | |
} else if (mode === bindingMode.twoWay) { | |
sourceExpression.connect(this, source); | |
this.targetObserver.subscribe(targetContext, this); | |
} | |
}; | |
Binding.prototype.unbind = function() { | |
if (!this.isBound) { | |
return; | |
} | |
this.isBound = false; | |
if (this.sourceExpression.unbind) { | |
this.sourceExpression.unbind(this, this.source); | |
} | |
if (this.originalSourceExpression) { | |
if (this.originalSourceExpression.unbind) { | |
this.originalSourceExpression.unbind(this, this.source); | |
} | |
this.sourceExpression = this.originalSourceExpression; | |
this.originalSourceExpression = null; | |
} | |
this.source = null; | |
if ('unbind' in this.targetObserver) { | |
this.targetObserver.unbind(); | |
} | |
if (this.targetObserver.unsubscribe) { | |
this.targetObserver.unsubscribe(targetContext, this); | |
} | |
this.unobserve(true); | |
} | |
Binding.prototype.replaceSourceExpression = function(expression) { | |
this.originalSourceExpression = this.sourceExpression; | |
this.sourceExpression = expression; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment