Aurelia 使可绑定行为在对象属性上可观察
Aurelia make bindable act as observable on object properties
在 Aurelia 绑定中,如果在一个组件中我们在 属性 上使用可观察装饰,并且如果 属性 是一个对象,那么我们将订阅该对象的所有属性。
例如:
import { observable } from 'aurelia-framework';
export class Car {
@observable color = {rgb: '', hex: ''};
colorChanged(newValue, oldValue) {
// this will fire whenever the 'color' property changes
}
}
因此,如果其中一个颜色属性发生变化,则会触发 colorChanged。但是在自定义元素中,我们有这样的可绑定对象:
import {bindable, bindingMode} from 'aurelia-framework';
export class SecretMessageCustomElement {
@bindable data;
dataChanged () {
// -------
}
}
那么 dataChanged 将不会在其属性更改时被调用。如何解决?
经过一些尝试,我编写了一些代码行来解决我的问题并希望能帮助到其他人。我已经订阅和取消订阅了发生的每个数据更改,并且每次都在每个字段上完成此订阅。所以这是解决方案:
import {
bindable,
BindingEngine
} from 'aurelia-framework';
@inject(Element, BindingEngine)
export class PaChartjs {
@bindable data;
@bindable options;
constructor(element, bindingEngine) {
this.element = element;
this.bindingEngine = bindingEngine;
}
bind() {
this.observeObject(this.data, 'data');
this.observeObject(this.options, 'options');
}
unbind() {
this.unobserveObjects();
}
unobserveObjects(groups) {
let self = this;
if (!groups) {
groups = Object.keys(this.subscriptions);
}
groups.forEach((groupitem, groupindex) => {
this.subscriptions[groupitem].forEach((subitem, subindex) => {
subitem.sub.dispose();
delete self.subscriptions[subindex];
}); //otherwise you'll bind twice next time
});
}
observeObject(obj, group) {
let self = this;
if (!this.subscriptions) {
this.subscriptions = [];
}
if (!this.subscriptions[group]) {
this.subscriptions[group] = [];
}
Object.keys(obj).forEach((keyitem, keyindex) => {
if (typeof obj[keyitem] === 'object' && obj[keyitem] !== null) {
self.observeObject(obj[keyitem]);
} else {
this.subscriptions[group].push({
obj: obj,
property: keyitem,
sub: this.bindingEngine
.propertyObserver(obj, keyitem) //e.g. subscribe to obj
.subscribe(() => this.objectPropertyChanged()) //subscribe to prop change
});
}
});
}
objectPropertyChanged(newValue, oldValue) {
this.heavyJobHandler(() => this.updateChartData());
}
dataChanged(newValue, oldValue) {
this.unobserveObjects(['data']);
if (this.chartObj) {
this.chartObj.data = newValue;
this.heavyJobHandler(() => this.updateChartData());
}
this.observeObject(this.data, 'data');
}
optionsChanged(newValue, oldValue) {
this.unobserveObjects(['data']);
if (this.chartObj) {
this.chartObj.options = options;
this.heavyJobHandler(() => this.updateChartData());
}
this.observeObject(this.options, 'options');
}
}
虽然这是代码的一部分,但它有主要思想。 TG.
@observable 不观察属性
这里有一个例子:https://gist.run/?id=040775f06aba5e955afd362ee60863aa
@observable color = { rgb: '', hex: '' }
colorChanged(val) { }
colorChanged
不会在rgb或hex改变时改变,只有当整个颜色属性重新分配时才会改变。
在 Aurelia 绑定中,如果在一个组件中我们在 属性 上使用可观察装饰,并且如果 属性 是一个对象,那么我们将订阅该对象的所有属性。
例如:
import { observable } from 'aurelia-framework';
export class Car {
@observable color = {rgb: '', hex: ''};
colorChanged(newValue, oldValue) {
// this will fire whenever the 'color' property changes
}
}
因此,如果其中一个颜色属性发生变化,则会触发 colorChanged。但是在自定义元素中,我们有这样的可绑定对象:
import {bindable, bindingMode} from 'aurelia-framework';
export class SecretMessageCustomElement {
@bindable data;
dataChanged () {
// -------
}
}
那么 dataChanged 将不会在其属性更改时被调用。如何解决?
经过一些尝试,我编写了一些代码行来解决我的问题并希望能帮助到其他人。我已经订阅和取消订阅了发生的每个数据更改,并且每次都在每个字段上完成此订阅。所以这是解决方案:
import {
bindable,
BindingEngine
} from 'aurelia-framework';
@inject(Element, BindingEngine)
export class PaChartjs {
@bindable data;
@bindable options;
constructor(element, bindingEngine) {
this.element = element;
this.bindingEngine = bindingEngine;
}
bind() {
this.observeObject(this.data, 'data');
this.observeObject(this.options, 'options');
}
unbind() {
this.unobserveObjects();
}
unobserveObjects(groups) {
let self = this;
if (!groups) {
groups = Object.keys(this.subscriptions);
}
groups.forEach((groupitem, groupindex) => {
this.subscriptions[groupitem].forEach((subitem, subindex) => {
subitem.sub.dispose();
delete self.subscriptions[subindex];
}); //otherwise you'll bind twice next time
});
}
observeObject(obj, group) {
let self = this;
if (!this.subscriptions) {
this.subscriptions = [];
}
if (!this.subscriptions[group]) {
this.subscriptions[group] = [];
}
Object.keys(obj).forEach((keyitem, keyindex) => {
if (typeof obj[keyitem] === 'object' && obj[keyitem] !== null) {
self.observeObject(obj[keyitem]);
} else {
this.subscriptions[group].push({
obj: obj,
property: keyitem,
sub: this.bindingEngine
.propertyObserver(obj, keyitem) //e.g. subscribe to obj
.subscribe(() => this.objectPropertyChanged()) //subscribe to prop change
});
}
});
}
objectPropertyChanged(newValue, oldValue) {
this.heavyJobHandler(() => this.updateChartData());
}
dataChanged(newValue, oldValue) {
this.unobserveObjects(['data']);
if (this.chartObj) {
this.chartObj.data = newValue;
this.heavyJobHandler(() => this.updateChartData());
}
this.observeObject(this.data, 'data');
}
optionsChanged(newValue, oldValue) {
this.unobserveObjects(['data']);
if (this.chartObj) {
this.chartObj.options = options;
this.heavyJobHandler(() => this.updateChartData());
}
this.observeObject(this.options, 'options');
}
}
虽然这是代码的一部分,但它有主要思想。 TG.
@observable 不观察属性
这里有一个例子:https://gist.run/?id=040775f06aba5e955afd362ee60863aa
@observable color = { rgb: '', hex: '' }
colorChanged(val) { }
colorChanged
不会在rgb或hex改变时改变,只有当整个颜色属性重新分配时才会改变。