javascript - Aurelia 中的数据绑定(bind)父子关系

标签 javascript aurelia

代码:

我有两个类(class):

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

}

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

然后我有一个 ShipmentUi具有发货实例的 View 模型 ( this.shipment )。

而在 ShipmentUi我构成 UI 的一部分的 View 显示允许选择小部件的 WidgetUi:

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

WigetUi 的 View 模型节省了运费。所以 WidgetUi 有一个 this.shipment .

然后widgetUi 的 View 显示了一个选择器:

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

问题设置:

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

这将使 WidgetUi 的 View 模型只得到一个 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中绑定(bind)子对象时,如果你想知道子对象的交换,你是否总是需要传入包含对象?

这个问题的原因是我的测试不是 100% 决定性的。所以我希望有人可以为我清除它。

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

再问(澄清):

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更改小部件的元素:

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

这次绑定(bind)到widget (而不是像我上面做的 this.shipment.widget)。

然后用户使用 select 选择一个名为“Dull Widget”的小部件。 .该小部件的值为“B7”。 “B7”是对名为“Dull Widget”的小部件的引用。

据我了解 JavaScript,WidgetUi 的 this.widget现在的值为“B7”(这是对“Dull Widget”的引用)。 (这是通过 Aurelia 数据绑定(bind)系统完成的。)

但是 ShipmentUi 的 this.shipment.widget仍然是“A3”(这是对“Sharp Widget”的引用)。

这不是我绑定(bind)时想要的this.shipment.widgetcompose元素。我希望小部件对象的更新反射(reflect)在发货中。 (注意,如果我刚刚更新了 widget.name ,那么它就会被更新。)

所以,据我所知,我必须将完整的父级传递给 compose元素(在本例中为 this.shipment),如果我想捕获分配。

我希望我错了(或者有一个解决方法),因为传递父对象让我分享“子”类不需要知道的细节。 (即它破坏了数据封装)

我想我可以在我的类(class)的每一层之间制作一个“持有人”。例如:this.shipment.holder.widgetholder只会在其中包含小部件。但这有点丑......我希望有另一种方式......

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

最佳答案

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

好消息:这正是@bindable旨在做到。您需要做的就是停止使用 compose 并使用 @bindable 制作自定义元素。表示自定义元素完成其工作所需的最少数据量的属性。例如:

小部件选择器.js

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

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

小部件选择器.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

关于javascript - Aurelia 中的数据绑定(bind)父子关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35560880/

相关文章:

javascript - Aurelia bindingEngine.propertyObserver - 检测属性何时因对象更改而更改

asp.net - 由于 HttpPlatformHandler,Aurelia 无法在 azure 上加载?

javascript - 如何在 aurelia-froala-editor 中更改语言环境?

checkbox - 如何使用 Aurelia 在取消选中和选中时调用函数

javascript - 将 Angular 传递给 IIFE block

javascript - ng-change 和 ng-click 在切换按钮 bootstrap-toggle 中不起作用

javascript - 将变量添加到 JavaScript 中的变量集

javascript - 使用 Javascript 单击按钮切换下拉列表启用和禁用?

javascript - 更改对象中的值

aurelia - 将对象传递给下一个兄弟组件