Aurelia 在自定义元素中绑定对象
Aurelia binding an object in a custom element
我有一个对象 'visit',它有几个属性(例如 visit1 = {id: 1, clientId: "0001", startTime: 1234567890, finishTime: 1234567899})。访问存储在数组 'shifts' 中,看起来像 shifts = [{id:1, visits: [visit1, ...]}, ...].
为了在视图中显示数据,我使用 repeat.for:
<div repeat.for="shift of shifts">
<ul>
<li repeat.for="visit of shift.visits">
<visit-item visit.bind="visit" settings.bind="userSettings" selectors="selectors"></visit-item>
</li>
</ul>
</div>
'visit-item' 是一个自定义元素,显示单次访问的可编辑表单。它的观点是:
<template>
<require from="./timepicker"></require>
<require from="../../converters/hour-format"></require>
<form class="form-horizontal" role="form">
<div class="col-xs-12 col-md-3 col-lg-3">
<label>start</label><input timepicker class="form-control input-sm" id="startTime_${visit.id}" type="text" value.bind="visit.startTime | hourFormat">
</div>
<div class="col-xs-12 col-md-3 col-lg-3">
<label>finish</label><input timepicker class="form-control input-sm" id="finishTime_${visit.id}" type="text" value.bind="visit.finishTime | hourFormat">
</div>
<div class="col-xs-12 col-md-3 col-lg-3">
<label>client</label><select class="form-control input-sm" id="client_${visit.id}" value.bind="visit.clientId">
<option repeat.for="option of selectors.client" model.bind="option.value" disabled.bind="option.disabled">${option.name}</option>
</select>
</div>
</form>
</template>
访问项的视图模型:
import {bindable, bindingMode} from 'aurelia-framework';
export class VisitItemCustomElement {
@bindable({ defaultBindingMode: bindingMode.twoWay }) visit;
@bindable selectors;
constructor() {
}
bind() {
}
visitChanged(newValue, oldValue) {
console.log("visit changed");
}
}
我尝试通过 visitChanged() 方法捕获访问形式的变化,但是当我更改表单中的值时,访问项的视图模型不会调用此方法。如果我执行 valueChanged() 也是一样。有没有什么方法可以用所描述的数据设计来捕捉表单的变化?
问题是 visit
没有改变,visit
上的属性正在改变。由于您只有少量要绑定的属性,因此最好通过在 visit-item
上为每个需要通知更改的 属性 创建一个可绑定的 属性 .
当我将表单中显示的所有属性作为单独的绑定变量包含在自定义元素中时,我设法捕获了更改。看起来很糟糕,因为我有很多房产要参观。如果您碰巧知道更好的解决方案,请告诉我
非常好@Ashley Grant。
当您想观察复杂对象的一个或某些属性时,我找到了解决方案。告诉我你的想法。
import {bindable, bindingMode, BindingEngine} from 'aurelia-framework';
@inject(BindingEngine)
export class VisitItemCustomElement {
@bindable({ defaultBindingMode: bindingMode.twoWay }) visit;
constructor(bindingEngine) {
this.bindingEngine = bindingEngine;
}
bind() {
this.subscription = this.bindingEngine
.propertyObserver(this.visit, 'clientId') //e.g. subscribe to visit.clientId
.subscribe(this.objectValueChanged); //subscribe to prop change
}
unbind() {
this.subscription.dispose(); //otherwise you'll bind twice next time
}
visitChanged(newValue, oldValue) {
console.log(`visit changed from: ${oldValue} to:${newValue}`);
if (this.subscription) {
this.subscription.dispose();
}
this.subscription = this.bindingEngine
.propertyObserver(this.visit, 'clientId')
.subscribe(this.objectValueChanged); // subscribe again in case obj changes!
};
}
objectValueChanged(newValue, oldValue) {
console.log(`objectValue changed from: ${oldValue} to:${newValue}`);
}
}
我有一个对象 'visit',它有几个属性(例如 visit1 = {id: 1, clientId: "0001", startTime: 1234567890, finishTime: 1234567899})。访问存储在数组 'shifts' 中,看起来像 shifts = [{id:1, visits: [visit1, ...]}, ...].
为了在视图中显示数据,我使用 repeat.for:
<div repeat.for="shift of shifts">
<ul>
<li repeat.for="visit of shift.visits">
<visit-item visit.bind="visit" settings.bind="userSettings" selectors="selectors"></visit-item>
</li>
</ul>
</div>
'visit-item' 是一个自定义元素,显示单次访问的可编辑表单。它的观点是:
<template>
<require from="./timepicker"></require>
<require from="../../converters/hour-format"></require>
<form class="form-horizontal" role="form">
<div class="col-xs-12 col-md-3 col-lg-3">
<label>start</label><input timepicker class="form-control input-sm" id="startTime_${visit.id}" type="text" value.bind="visit.startTime | hourFormat">
</div>
<div class="col-xs-12 col-md-3 col-lg-3">
<label>finish</label><input timepicker class="form-control input-sm" id="finishTime_${visit.id}" type="text" value.bind="visit.finishTime | hourFormat">
</div>
<div class="col-xs-12 col-md-3 col-lg-3">
<label>client</label><select class="form-control input-sm" id="client_${visit.id}" value.bind="visit.clientId">
<option repeat.for="option of selectors.client" model.bind="option.value" disabled.bind="option.disabled">${option.name}</option>
</select>
</div>
</form>
</template>
访问项的视图模型:
import {bindable, bindingMode} from 'aurelia-framework';
export class VisitItemCustomElement {
@bindable({ defaultBindingMode: bindingMode.twoWay }) visit;
@bindable selectors;
constructor() {
}
bind() {
}
visitChanged(newValue, oldValue) {
console.log("visit changed");
}
}
我尝试通过 visitChanged() 方法捕获访问形式的变化,但是当我更改表单中的值时,访问项的视图模型不会调用此方法。如果我执行 valueChanged() 也是一样。有没有什么方法可以用所描述的数据设计来捕捉表单的变化?
问题是 visit
没有改变,visit
上的属性正在改变。由于您只有少量要绑定的属性,因此最好通过在 visit-item
上为每个需要通知更改的 属性 创建一个可绑定的 属性 .
当我将表单中显示的所有属性作为单独的绑定变量包含在自定义元素中时,我设法捕获了更改。看起来很糟糕,因为我有很多房产要参观。如果您碰巧知道更好的解决方案,请告诉我
非常好@Ashley Grant。
当您想观察复杂对象的一个或某些属性时,我找到了解决方案。告诉我你的想法。
import {bindable, bindingMode, BindingEngine} from 'aurelia-framework';
@inject(BindingEngine)
export class VisitItemCustomElement {
@bindable({ defaultBindingMode: bindingMode.twoWay }) visit;
constructor(bindingEngine) {
this.bindingEngine = bindingEngine;
}
bind() {
this.subscription = this.bindingEngine
.propertyObserver(this.visit, 'clientId') //e.g. subscribe to visit.clientId
.subscribe(this.objectValueChanged); //subscribe to prop change
}
unbind() {
this.subscription.dispose(); //otherwise you'll bind twice next time
}
visitChanged(newValue, oldValue) {
console.log(`visit changed from: ${oldValue} to:${newValue}`);
if (this.subscription) {
this.subscription.dispose();
}
this.subscription = this.bindingEngine
.propertyObserver(this.visit, 'clientId')
.subscribe(this.objectValueChanged); // subscribe again in case obj changes!
};
}
objectValueChanged(newValue, oldValue) {
console.log(`objectValue changed from: ${oldValue} to:${newValue}`);
}
}