Aurelia 中的数据绑定父子关系 [英] Data binding parent-child relationships in Aurelia

查看:23
本文介绍了Aurelia 中的数据绑定父子关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个班级:

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

}

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

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

Then I have a ShipmentUi view-model that has an instance of shipment (this.shipment).

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

And in the ShipmentUi view I compose part of the UI show the WidgetUi that allows selection of the Widget:

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

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

The WigetUi's view-model saves off the shipment. So WidgetUi has a this.shipment.

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

And then widgetUi's view shows a selector:

<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.它应该不需要关心它是用于装运还是用于其他用途.)

This would have WidgetUi's view-model only get a this.widget. (The WidgetUi class does not need to see or know about the shipment. Its sole function is to allow selecting a Widget. It should not need to care if it is for a shipment or for something else.)

但是,据我了解 Javascript,这是行不通的.

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

Because if I just pass in the reference to shipment.widget, then WidgetUi will have just a reference to the widget part. At first WidgetUi's this.widget will have the same reference as ShipmentUi's this.shipment.widget.

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

But when the user selects a different widget, WidgetUi this.widget will get a different reference (to the newly selected widget in the dropdown). But ShipmentUi's this.shipment.widget will will still reference the original widget.

在Javascript中绑定子对象时,如果想知道子对象的交换,是不是总是需要传入包含对象?

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

The reason for this question is that my tests are not 100% conclusive. So I am hoping someone can clear it up for me.

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

I am also hoping I am wrong somehow, as I really don't like the idea of having to expose all the data in the containing classes. (Giving access to shipment in the WigetUi class in this case.)

Fabio Luz 要求澄清我的问题.所以这是一个尝试.这将遍历上面的示例,但将其更改为我希望它工作的方式.

Fabio Luz requested some clarification on what I am asking. So here is an attempt. This walks through the example above, but changing it to the way I would LIKE it to work.

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

I have two Widgets. Sharp Widget and Dull Widget.

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

ShipmentUi.js:
This class has the variable this.shipment.widget. I am going to say that its value is 'A3' (arbitrary memory value). 'A3' is a reference to a widget that has a name of 'Sharp Widget'.

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

I then pass the widget down to the WidgetUi class:

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

WidgetUi.js:
WidgetUi 类具有:

WidgetUi.js:
The WidgetUi class has:

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

所以现在在 WidgetUi 中 this.widget 也有一个值 'A3'.该值是对名称为Sharp Widget"的 Widget 的内存引用.

So now in WidgetUi this.widget also has a value of 'A3'. That value is a memory reference to the Widget that has a name of 'Sharp Widget'.

现在用户使用这个 select 元素来改变 Widget:

Now the user uses this select element to change the 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).

This time I bind to widget (instead of this.shipment.widget like I did above).

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

Then user picks a widget with the name of 'Dull Widget' using the select. That widget has a value of 'B7'. And 'B7' is a reference to the widget named 'Dull Widget'.

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

As I understand JavaScript, WidgetUi's this.widget now has a value of 'B7' (which is a reference to 'Dull Widget'). (This is done via the Aurelia data binding system.)

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

But ShipmentUi's this.shipment.widget is still 'A3' (which is a reference to 'Sharp Widget').

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

This is not what I wanted when I bound this.shipment.widget to the compose element. I wanted the updates to the widget object to be reflected in the shipment. (Note, if I had just updated widget.name, then it would have been updated.)

所以,从我所见,如果我想要一个要捕获的任务.

So, from what I can see, I have to pass in the full parent to the compose element (this.shipment in this case), if I want an assignment to be captured.

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

I am hoping I am wrong (or there is a workaround), because passing the parent object makes me share details that the "child" class does not need to know about. (ie it breaks data encapsulation)

我想我可以在我的课程的每一层之间制作一个支架".例如: this.shipment.holder.widgetholder 将只包含小部件.但这有点丑......我希望有另一种方式......

I guess I could make a "holder" between each layer of my classes. For Example: this.shipment.holder.widget and holder would just have the widget in it. But this is kinda ugly... I hope there is another way...

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

So, my question is: Am I right with my above statements? And if I am, is there another way that keeps my object model clean?

推荐答案

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

If I understand the question correctly you're looking for a way to share the minimum amount of data with the widgetui component. Instead of giving it the whole shipment object so that it can manipulate the shipment.widget property, you'd rather give it a property accessor to the widget property.

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

Good news: this is exactly what @bindable is designed to do. All you'll need to do is stop using compose and craft a custom element with @bindable properties representing the minimum amount of data the custom element needs to do it's job. For example:

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

这篇关于Aurelia 中的数据绑定父子关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆