代码:
我有两节课:
export class Shipment {
shipmentId: number;
widget: Widget;
}
export class Widget {
widgetId: number;
name: string;
}
然后我有一个ShipmentUi视图模型,它有一个发货实例(this.shipment).
在ShipmentUi视图中,我构建了部分UI,显示了允许选择Widget的WidgetUi:
WigetUi的视图模型可以节省出货量.所以WidgetUi有一个this.shipment.
然后widgetUi的视图显示一个选择器:
问题设置:
在我的撰写标签中(在ShipmentUi的视图中),我宁愿绑定到shipment.widget.
这将使WidgetUi的视图模型只获得一个this.widget. (WidgetUi类不需要查看或了解货物.它的唯一功能是允许选择Widget.它不需要关心它是用于货物还是其他东西.)
但是,正如我理解Javascript,这是行不通的.
因为如果我只是传递对shipment.widget的引用,那么WidgetUi将只有对widget部分的引用.起初WidgetUi的this.widget将与ShipmentUi的this.shipment.widget具有相同的引用.
但是当用户选择不同的小部件时,WidgetUi this.widget将获得不同的引用(对于下拉列表中新选择的小部件).但是ShipmentUi的this.shipment.widget仍将引用原始小部件.
问题:
在Javascript中绑定到子对象时,如果要了解子对象的交换,是否总是必须传入包含对象?
这个问题的原因是我的测试不是100%确定的.所以我希望有人能为我清理它.
我也希望我错了,因为我真的不喜欢必须公开包含类中的所有数据. (在这种情况下,允许访问WigetUi类中的货件.)
重新询问(澄清):
Fabio Luz要求澄清我的要求.所以这是一次尝试.这将介绍上面的示例,但将其更改为我希望它工作的方式.
我有两个小部件. Sharp Widget和Dull Widget.
ShipmentUi.js:
这个类有变量this.shipment.widget.我要说它的值是’A3′(任意内存值). “A3”是对名称为“Sharp Widget”的小部件的引用.
然后我将小部件传递给WidgetUi类:
WidgetUi.js:
WidgetUi类具有:
activate(widget: Widget) {
this.widget = widget;
}
所以现在在WidgetUi中,this.widget的值也是’A3′.该值是对Widget的内存引用,其名称为“Sharp Widget”.
现在用户使用此select元素来更改Widget:
这次我绑定到widget(而不是像我上面那样的this.shipment.widget).
然后用户使用select选择名为“Dull Widget”的小部件.该小部件的值为“B7”. ‘B7’是对名为’Dull Widget’的小部件的引用.
据我了解JavaScript,WidgetUi的this.widget现在的值为’B7′(这是对’Dull Widget’的引用). (这是通过Aurelia数据绑定系统完成的.)
但是ShipmentUi的this.shipment.widget仍然是’A3′(这是对’Sharp Widget’的引用).
当我将this.shipment.widget绑定到compose元素时,这不是我想要的.我希望小部件对象的更新能够反映在货件中. (注意,如果我刚刚更新了widget.name,那么它就会被更新.)
所以,从我所看到的,我必须将完整的父元素传递给compose元素(在本例中为this.shipment),如果我想要捕获一个赋值.
我希望我错了(或者有一个解决方法),因为传递父对象会让我分享“子”类不需要知道的细节. (即它打破了数据封装)
我想我可以在课程的每一层之间建立一个“持有者”.例如:this.shipment.holder.widget和holder将只包含其中的小部件.但这有点丑……我希望还有另一种方式……
所以,我的问题是:我对上述陈述是否正确?如果我是,还有另一种方法可以保持我的对象模型干净吗?
好消息:这正是@bindable的目的.您需要做的就是停止使用compose并使用@bindable属性创建一个自定义元素,该属性表示自定义元素执行它所需的最小数据量.例如:
窗口小部件,picker.js
import {bindable,bindingMode} from 'aurelia-framework';
export class WidgetPicker {
@bindable({ defaultBindingMode: bindingMode.twoWay }) widget;
@bindable widgets;
}
窗口小部件,picker.html
用法:
例: