Skip to content

Instantly share code, notes, and snippets.

@gronostajo
Created June 5, 2017 22:33
Show Gist options
  • Save gronostajo/f714bab83598d6ff8809dcbad65142b0 to your computer and use it in GitHub Desktop.
Save gronostajo/f714bab83598d6ff8809dcbad65142b0 to your computer and use it in GitHub Desktop.
@observable bug demo
<template>
<require from="./foo"></require>
<style scoped>
p {
max-width: 400px;
line-height: 1.3;
}
</style>
<h1>@observable bug demo</h1>
<p>There's a component <code>&lt;foo&gt;</code> below which contains a component <code>&lt;bar&gt;</code>. Both components have <code>value</code> fields which are bound with a two-way binding and initially undefined. <code>Foo.value</code> is <code>@observable</code>. Both components have <code>valueChanged()</code> methods.</p>
<p><code>&lt;bar&gt;</code> contains a button which assigns <code>'qwerty'</code> to <code>Bar.value</code>. The method <code>Bar.valueChanged()</code> is called, followed by <code>Foo.valueChanged()</code> as the change propagates up through a two-way binding. This is fine</p>
<p><code>Foo.valueChanged()</code> assigns <code>undefined</code> to its <code>value</code>. This causes <code>Foo.valueChanged()</code> to be called again, which is expected.</p>
<p>However, the change doesn't propagate down to <code>&lt;bar&gt;</code> and its <code>valueChanged()</code> doesn't fire.</p>
<p>Changing <code>@observable</code> to <code>@bindable</code> fixes this. Values other than <code>undefined</code> behave properly both with <code>@observable</code> and <code>@bindable</code>.</p>
<foo></foo>
</template>
export class App {
}
<template>
<div>
Bar: ${'[' + value + '] is undefined? ' + (value == undefined)}
<button click.delegate="changeValue()">Change value</button>
</div>
</template>
import {bindable} from 'aurelia-framework';
import {bindingMode} from "aurelia-binding";
export class Bar {
@bindable({defaultBindingMode: bindingMode.twoWay}) value;
valueChanged() {
console.log('Bar: value changed: ' + this.value);
if (this.value == undefined) {
return;
}
}
changeValue() {
this.value = 'qwerty';
}
}
<template>
<require from="./bar"></require>
<div>
Foo: ${'[' + value + '] is undefined? ' + (value == undefined)}
</div>
<bar value.bind="value"></bar>
</template>
import {bindable, observable} from 'aurelia-framework';
export class Foo {
@observable value;
valueChanged() {
console.log('Foo: value changed: ' + this.value);
if (this.value == undefined) {
return;
}
console.log('Foo: setting value to undefined');
// Bug: this won't cause Bar.valueChanged() to fire if this.value is @observable,
// but just make this.value @bindable instead of @observable and it will work.
// Values other than undefined work with both.
// Expected behavior: Bar.valuechanges when @observable value is assigned undefined
this.value = undefined;
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment