Seems really weird to be put a dataModel property on an object whose sole
purpose is be a grouping mechanism. I understand wanting to preserve the
model/view/controller paradigm, but wouldn't it more efficient to give the
data model to the things that actually need the data model in as direct a
fashion as possible? The data is readily available in this class that has
this structure and passing it to the widgets individually via data binding
would make things a lot easier than having to have these components
discover the data in their life cycles.

I have to really look over how I created the whole mobile component
classes and make sure they conform to this pattern because I think it will
be some re-writing. Maybe not too much, but I have to go and wrap my head
around it.

—peter

On 8/17/16, 7:10 PM, "Alex Harui" <[email protected]> wrote:

>OK, I think I get it now.  The key thing is that the "View" isn't really a
>view like a ButtonView or CheckBoxView is to Button or Checkbox.  Instead,
>a View is a top-level component.
>
>Application is a top-level component.  It has a "model", "controller", and
>"initialView" property.  You were able to eliminate circularities by
>having the 3 rules below because the controller is referencing the
>"initialView" and "model" and not the Application (as it should).
>
>The equivalent for StackedViewManager may require terms borrowed from the
>Flex SDK: "navigator" and "navigatorContent".  If StackedViewManager is
>actually a StackNavigator and there was a NavigatorContent tag with view
>and controller, that would be more similar to the Application pattern:
>
><StackedNavigator>
>  <NavigatorContent title="Watch List" dataModel="{applicationModel}">
>    <view>
>      <View>
>        UI Widgets
>      </View>
>    </view>
>    <controller>
>      <WatchListController />
>    </controller>
>  </NavigatorContent>
></StackedNavigator>
>
>And I think that would also eliminate circularities because the controller
>would be referencing the View and not the NavigatorContent.
>
>Thoughts?
>-Alex
>
>On 8/17/16, 2:29 PM, "Peter Ent" <[email protected]> wrote:
>
>>
>>
>>On 8/17/16, 5:09 PM, "Alex Harui" <[email protected]> wrote:
>>
>>>Peter,
>>>
>>>I like the idea of declaring the controller as a bead in the view.
>>>
>>>But shouldn't the controller be able to know about (have references to)
>>>the View as long as the View doesn't know about the controller (which it
>>>shouldn't, IMO).
>>As soon as I added the controller has a bead, the circular dependency was
>>formed. I had started with the previous changes where I had removed the
>>circular dependency - the controller was just referenced in the CSS.
>>>
>>>The view should dispatch events (for example, converting a "click" on a
>>>checkbox to "LicenseAcceptanceCheckboxSelectionChange" but it should be
>>>ok
>>>for the  controller to have a reference to the view to access data from
>>>the widgets, validate them, and then apply them to the model.  Passing
>>>data via events means copying data and references and the controller
>>>code
>>>might need other values from other widgets in the view.  It also means
>>>fewer custom event classes.
>>
>>I thought using custom events was a nice way to separate the concerns.
>>What do other people think - do you use a lot of custom events in your
>>application code or do you get some simple event and then go grab the
>>data
>>out of the controls?
>>
>>>
>>>IMO:
>>>Models should not reference views or controllers
>>>Views should reference models but not controllers
>>>Controllers should reference models and views.
>>
>>I don't see how you can remove the dependency when the View MXML explicit
>>references the Controller MXML in the <js:beads> list. Perhaps we have
>>something wrong in the fundamentals then.
>>
>>>
>>>I think there aren't circularities in that set.
>>>
>>>Thoughts?
>>>-Alex
>>>
>>>On 8/17/16, 1:46 PM, "Peter Ent" <[email protected]> wrote:
>>>
>>>>This is what I'm concluding in MobileTrader:
>>>>
>>>>MobileTrader has "sub-views" for WatchList and Alerts. Each of these
>>>>sub-views has its own controller (WatchListController,
>>>>AlertViewController) which are responsible for taking events from the
>>>>view
>>>>and updating the model.
>>>>
>>>>The first task is to get the controller to know about the model. We are
>>>>talking about the model holding the data, not the FlexJS "model" which
>>>>most components have that hold values for the component's properties.
>>>>So
>>>>I'm calling this the "dataModel". The circular dependencies are arising
>>>>because the controllers are directly references their views and
>>>>grabbing
>>>>data out of the view.
>>>>
>>>>I removed the attachment of the controller to the sub-view from the
>>>>CSS.
>>>>In the view (eg, WatchListView), I explicitly name the controller bead
>>>>and
>>>>use data binding to pass in the model the controller needs to use.
>>>>
>>>><js:beads>
>>>>    <js:ViewDataBinding>
>>>>    <controller:WatchListController dataModel="{dataModel}" />
>>>></js:beads>
>>>>
>>>>(Note: The WatchListView's dataModel is set using data binding from the
>>>>outer MyInitialView).
>>>>
>>>>Then I removed all references to WatchListView from
>>>>WatchListController.
>>>>This caused several errors because WatchListController was referencing
>>>>the
>>>>view to get to the data on the screen which needed. For example, it
>>>>needed
>>>>the symbol to watch:
>>>>
>>>>view.symbolName.text
>>>>
>>>>Since WatchListController now knows nothing about the view, I created
>>>>custom events for the WatchListView to dispatch that contained the data
>>>>the controller needs. So when the Set button is picked, the button's
>>>>event
>>>>handler in WatchListView now does:
>>>>
>>>>var event: new AddSymbolEvent(symbolName.text);
>>>>dispatchEvent(event);
>>>>
>>>>The WatchListController is looking for this event and can use the
>>>>symbol
>>>>value from the event without referring to the view at all.
>>>>
>>>>I applied this technique to the AlertsView and AlertsViewController.
>>>>All
>>>>in all, the code got cleaner and more readable. The view takes care of
>>>>updating the view UI components and the controller takes care of
>>>>updating
>>>>the model.
>>>>
>>>>The pattern now works something like this:
>>>>
>>>>1. Give the sub-view controller bead bindable get/set methods for the
>>>>dataModel it needs. Don't forget to add the ViewDataBinding bead to the
>>>>sub-view class.
>>>>2. Create custom events to pass data from the sub-view controls over to
>>>>the controller.
>>>>3. Have the controller set up event listeners for these custom events
>>>>in
>>>>its strand-setter; the "strand" is really the sub-view.
>>>>4. When the view receives some user interaction, have it create a
>>>>custom
>>>>event with the data and dispatch it.
>>>>5. The controller will receive the custom event and modify the model.
>>>>6. The view can update the UI controls (eg, textField.text = "") after
>>>>sending the event.
>>>>
>>>>For simpler projects, like the TodoListSample or DataBindingExample,
>>>>the
>>>>controller can implement IDocument and, when the "document" (aka,
>>>>Application) is set, it can get the reference to the application data
>>>>model and set up listeners for it.
>>>>
>>>>I will be checking these changes in shortly today or tomorrow (USA,
>>>>EDT)
>>>>morning.
>>>>
>>>>‹peter
>>>>
>>>>On 8/16/16, 8:33 PM, "Alex Harui" <[email protected]> wrote:
>>>>
>>>>>
>>>>>
>>>>>On 8/16/16, 2:20 PM, "Peter Ent" <[email protected]> wrote:
>>>>>
>>>>>>
>>>>>>Hi,
>>>>>>
>>>>>>I wanted to post what I've done before I commit the code to get an
>>>>>>idea
>>>>>>if
>>>>>>this is the right approach.
>>>>>>
>>>>>>Background: a circular dependency is when class A references class B
>>>>>>which
>>>>>>references class B. Pretty simple.
>>>>>>
>>>>>>In many of the FlexJS examples, there are circular dependencies
>>>>>>between
>>>>>>the application class and the application's controller. For example,
>>>>>>DataBindingExampleApp references its controller, MyController, which
>>>>>>has
>>>>>>a
>>>>>>reference back to the application. Likewise, the TodoListSampleApp
>>>>>>references its controller which holds a reference to the app class.
>>>>>>The
>>>>>>objective in both examples is provide the controller with a reference
>>>>>>to
>>>>>>the model.
>>>>>>
>>>>>>In both of these cases, my solution is to remove the explicit
>>>>>>reference
>>>>>>to
>>>>>>the application (eg, DataBindingExample) in the controller and
>>>>>>replace
>>>>>>it
>>>>>>with the Application class and then extract what it needs into local
>>>>>>variables. 
>>>>>
>>>>>The above sounds like a good plan.
>>>>>
>>>>>>However, MobileTrader is bit trickier. MobileTrader has several
>>>>>>mobile
>>>>>>"views" and each has its own controller. The circular dependency in
>>>>>>this
>>>>>>case is between these secondary views and their respective
>>>>>>controllers.
>>>>>>The way I approached this was to make a new interface in the
>>>>>>MobileTrader
>>>>>>example src, called "IBeadControllerWithModel" which extends
>>>>>>IBeadController and adds a getter/setter for a model. Now the view
>>>>>>can
>>>>>>simple reference its controller using this new interface and set the
>>>>>>model
>>>>>>so the controller can now modify it.
>>>>>
>>>>>I don't know this code very well, but I poked around a bit and it
>>>>>appears
>>>>>the view knows about the controller only because it is assigning the
>>>>>model
>>>>>to the controller.  IMO, the controller should pick up the model from
>>>>>the
>>>>>strand.  If it is a timing issue where the model isn't set when the
>>>>>controller is put on the strand, the controller should be able to look
>>>>>for
>>>>>a modelChange event or maybe even initComplete.
>>>>>
>>>>>Thoughts?
>>>>>-Alex
>>>>>
>>>>
>>>
>>
>

Reply via email to