繁体   English   中英

Aurelia中的数据绑定父子关系

[英]Data binding parent-child relationships in Aurelia

代码:

我有两节课:

export class Shipment {
    shipmentId: number;
    widget: Widget;

}

export class Widget {
    widgetId: number;
    name: string;
}

然后我有一个ShipmentUi视图模型,它有一个发货实例( this.shipment )。

ShipmentUi视图中,我构建了部分UI,显示了允许选择Widget的WidgetUi:

<compose view-model="src/views/widgetUi" model.bind="shipment"></compose>

WigetUi的视图模型可以节省出货量。 所以WidgetUi有一个this.shipment

然后widgetUi的视图显示一个选择器:

<select value.bind="shipment.widget" >
    <option class="dropdown-toggle" repeat.for="widget of widgets"
            model.two-way="widget">${widget.name}</option>
</select>

问题设置:

在我的撰写标签中(在ShipmentUi的视图中),我宁愿绑定到shipment.widget

这将使WidgetUi的视图模型只获得一个this.widget WidgetUi类不需要查看或了解shipment 。它的唯一功能是允许选择Widget 。它不需要关心它是用于货物还是其他东西。)

但是,正如我理解Javascript,这是行不通的。

因为如果我只是传递对shipment.widget的引用,那么WidgetUi将只有对widget部分的引用。 起初WidgetUi的this.widget将与ShipmentUi的this.shipment.widget具有相同的引用。

但是当用户选择不同的小部件时,WidgetUi this.widget将获得不同的引用(对于下拉列表中新选择的小部件)。 但是ShipmentUi的this.shipment.widget仍将引用原始小部件。

问题:

在Javascript中绑定到子对象时,如果要了解子对象的交换,是否总是必须传入包含对象?

这个问题的原因是我的测试不是100%确定的。 所以我希望有人能为我清理它。

我也希望我错了,因为我真的不喜欢必须公开包含类中的所有数据。 (在这种情况下, WigetUi访问WigetUi类中的shipment 。)


重新询问(澄清):

Fabio Luz要求澄清我的要求。 所以这是一次尝试。 这将介绍上面的示例,但将其更改为我希望它工作的方式。

我有两个小部件。 Sharp Widget和Dull Widget。

ShipmentUi.js:
这个类有变量this.shipment.widget 我要说它的值是'A3' (任意内存值)。 'A3'是对名称为'Sharp Widget'的小部件的引用。

然后我将小部件传递给WidgetUi类:

<compose view-model="src/views/widgetUi" model.bind="shipment.wiget"></compose>

WidgetUi.js:
WidgetUi类具有:

activate(widget: Widget) {
   this.widget = widget;
}

所以现在在WidgetUi中, this.widget的值也是'A3'。 该值是对Widget的内存引用,其名称为“Sharp Widget”。

现在用户使用此select元素来更改Widget:

<select value.bind="widget" >
    <option class="dropdown-toggle" repeat.for="widget of widgets"
            model.two-way="widget">${widget.name}</option>
</select>

这次我绑定到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.widgetholder将只包含其中的小部件。 但这有点难看...我希望还有另一种方式......

所以,我的问题是:我对上述陈述是否正确? 如果我是,还有另一种方法可以保持我的对象模型干净吗?

如果我正确理解了这个问题,那么您正在寻找一种与widgetui组件共享最小数据量的方法。 而不是给它整个装运对象,以便它可以操作shipment.widget属性,而不是给它一个属性访问器到小部件属性。

好消息:这正是@bindable的目的。 您需要做的就是停止使用compose并使用@bindable属性创建一个自定义元素, @bindable属性表示自定义元素执行它所需的最小数据量。 例如:

窗口小部件,picker.js

import {bindable, bindingMode} from 'aurelia-framework';

export class WidgetPicker {
  @bindable({ defaultBindingMode: bindingMode.twoWay }) widget;
  @bindable widgets;
}

窗口小部件,picker.html

<select value.bind="widget">
  <option repeat.for="widget of widgets" model.bind="widget">${widget.name}</option>
</select>

用法:

<widget-picker widget.bind="shipment.widget" widgets.bind="widgets"></widget-picker>

例:

https://gist.run/?id=4c726da335aaecefd80b

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM