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

查看:101
本文介绍了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: / p>

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 类不需要查看或了解货件。它的唯一功能是允许选择 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将会有只是对小部件的引用。首先,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 类中访问 shipping 。)

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类has:

WidgetUi.js:
The WidgetUi class has:

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

现在在WidgetUi this.widget 的值也为'A3'。该值是对Widget的内存引用,其名称为Sharp 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'.

现在用户使用此选择要更改小部件的元素:

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>

这次我绑定到小部件(而不是 this.shipment.widget 就像我上面所做的那样。)

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

然后用户选择一个名为'的小部件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时,这不是我想要的/ code>到 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.)

所以,从我所看到的,我必须将完整的父母传递给 compose 元素( this.shipment case),如果我想要捕获一个赋值。

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

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天全站免登陆