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