【问题标题】:Data binding parent-child relationships in AureliaAurelia 中的数据绑定父子关系
【发布时间】:2016-02-22 18:14:03
【问题描述】:

守则:

我有两个班级:

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,这是行不通的。

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

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

问题:

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

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

我也希望我错了,因为我真的不喜欢必须公开包含类中的所有数据的想法。 (在这种情况下,在 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'。该值是对名称为“Sharp Widget”的 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 将只包含小部件。但这有点难看...我希望有另一种方法...

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

【问题讨论】:

  • 我看到你花了这么多精力把你的问题说清楚,但我还是不明白你在问什么=/
  • @FabioLuz - 我用更多细节更新了我的问题。

标签: javascript aurelia


【解决方案1】:

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

好消息:这正是@bindable 的设计目的。您需要做的就是停止使用 compose 并制作具有 @bindable 属性的自定义元素,该属性表示自定义元素完成其工作所需的最小数据量。例如:

widget-picker.js

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

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

widget-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

【讨论】:

  • 更新了 html 并添加了一个示例——widget-picker.html 中有一个错字
猜你喜欢
  • 2013-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
  • 1970-01-01
  • 2022-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多