簡體   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