Skip to content

Instantly share code, notes, and snippets.

@gronostajo
Forked from jdanyow/app.html
Last active September 7, 2017 13:09
Show Gist options
  • Save gronostajo/2cac8c024cac4c9b921bcbe7b9e0b115 to your computer and use it in GitHub Desktop.
Save gronostajo/2cac8c024cac4c9b921bcbe7b9e0b115 to your computer and use it in GitHub Desktop.
Array modifications don't trigger bindings
<template>
<require from="./toggle"></require>
<input type="checkbox" model.one-time="model" checked.bind="items">
<toggle model.one-time="model" array.bind="items"></toggle>
<button click.delegate="reassign()">Reassign array</button>
<h3>Manual:</h3>
<p>Checkbox and <code>&lt;toggle&gt;</code> custom element are both bound to the same array and are expected to do the same thing.</p>
<p>Clicking <i>Toggle</i> will modify <code>items</code> array and toggle internal flag. The checkbox will react to array's change. Getter won't be triggered.</p>
<p>Clicking the checkbox will update array, but <code>&lt;toggle&gt;</code> won't realize. Array updates don't trigger bindings.</p>
<p>Clicking <i>Reassign array</i> will replace <code>items</code> array with its shallow copy. That will trigger all bindings properly.</p>
<p>Ensure that checkbox is unchecked and property and getter are false. Check the checkbox. Click <i>Toggle</i>. Checkbox will uncheck. This shows that <code>&lt;toggle&gt;</code> can access updated array, but <code>arrayChanged</code> doesn't get called.</p>
</template>
export class App {
model = 1;
items = [];
reassign() {
this.items = this.items.concat();
}
}
<!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://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
<template>
<div>
property: ${enabled} getter: ${enabledGetter}
<button click.delegate="toggle()">Toggle</button>
</div>
</template>
import {bindable} from "aurelia-templating";
import {bindingMode, computedFrom} from "aurelia-binding";
export class Toggle {
@bindable model;
@bindable({defaultBindingMode: bindingMode.twoWay}) array = [];
enabled = false;
arrayChanged() {
if (this.model == undefined) return;
this.enabled = this.array.indexOf(this.model) != -1;
}
toggle() {
this.enabled = this.array.indexOf(this.model) != -1;
if (this.enabled) {
const index = this.array.indexOf(this.model);
this.array.splice(index, 1);
} else {
this.array.push(this.model);
}
this.enabled = !this.enabled;
}
@computedFrom('array')
get enabledGetter() {
return this.array.indexOf(this.model) != -1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment