Code:
I have two classes:
export class Shipment { shipmentId: number; widget: Widget; } export class Widget { widgetId: number; name: string; }
Then I have a ShipmentUi view model that has a dispatch instance ( this.shipment ).
And in the ShipmentUi view, I am part of the user interface, showing WidgetUi, which allows us to select the Widget:
<compose view-model="src/views/widgetUi" model.bind="shipment"></compose>
The WigetUi view model eliminates shipping. So WidgetUi has this.shipment .
And then the widgetUi 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>
Question setup:
In my compose tag (in the ShipmentUi view), I prefer to bind to shipment.widget .
This will have a WidgetUi model view only by receiving this.widget . (The WidgetUi class WidgetUi not see or know about shipment . Its only function is to allow Widget to be selected. There is no need to worry about whether it is for dispatch or for something else.)
But since I understand Javascript, this will not work.
Because if I just pass the link to shipment.widget, then WidgetUi will only have a link to the widget part. First, WidgetUi this.widget will have the same link as ShipmentUi this.shipment.widget .
But when the user selects another widget, WidgetUi this.widget will get a different link (for the newly selected widget in the drop-down list). But ShipmentUi this.shipment.widget will still reference the original widget.
Question:
When binding to child objects in Javascript, do you always need to pass to the contained object if you want to know about swapping the child?
The reason for this question is that my tests are not 100% convincing. Therefore, I hope someone can clean it.
I also hope that I'm wrong, as I really don't like the idea of exposing all the data in the contained classes. (Providing access to shipment in the WigetUi class in this case.)
Repeated request (clarification):
Fabio Luz asked me to clarify what I ask. So here is an attempt. This is looked at by the above example, but changes it the way I would like it to work.
I have two widgets. Sharp Widget and Dull Widget.
ShipmentUi.js:
This class has the variable this.shipment.widget . I'm going to say that its value is 'A3' (arbitrary memory value). "A3" is a link to a widget named "Sharp Widget".
Then I pass the widget to the WidgetUi class:
<compose view-model="src/views/widgetUi" model.bind="shipment.wiget"></compose>
WidgetUi.js:
The WidgetUi class has:
activate(widget: Widget) { this.widget = widget; }
So now in WidgetUi this.widget also has the value "A3". This value is a reference to the widget's memory named "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 time I am attached to Widget (instead of this.shipment.widget , as I did above).
The user then selects a widget named "Dull Widget" using select . This widget has a value of "B7". And "B7" is a link to the "Dull Widget" widget.
As I understand JavaScript, WidgetUi this.widget now has a value of "B7" (this is a link to "Dull Widget"). (This is done through the Aurelia data binding system.)
But ShipmentUi this.shipment.widget is still “A3” (this is a link to “Sharp Widget”).
This is not what I wanted by linking this.shipment.widget to the compose element. I wanted updates to the widget object to be reflected in the shipment. (Note that if I just updated widget.name , it would be updated.)
So, from what I see, I need to pass the full parent to the compose element ( this.shipment in this case) if I want the destination to be captured.
I hope that I am mistaken (or there is a workaround), because passing the parent object allows me to exchange details that the "child" class should not know about. (i.e. interrupts data encapsulation)
I think I could create a “holder” between each layer of my classes. For example: this.shipment.holder.widget and holder will only have a widget. But this is disgusting ... I hope there is another way ...
So my question is: do I agree with my statements above? And if so, is there any other way to keep my object model clean?