-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Since no one seems to be following up in this thread http://www.zkoss.org/forum/listComment/18752-Event-Queue-subscribed-more-than-once, I'll briefly explain the issue.
When trying to use an MVVM pattern, you often see suggestions to use Composers for things where you are dealing more directly with the UI elements (the idea being that ViewModels shouldn't know about a UI elements.
However in order for a ViewModel to notify a Composer of an event, you can't just listen for a regular global command, it has to subscribe to a queue with a listener and your ViewModel has to send out a global command to that queue.
From the above thread though this seems to have a lot of messy issues with having to clean up listeners, whereas instead of using a Composer I just use a ViewModel I don't have those issues. In fact the ViewModel code and the Composer look almost identical.
Am I taking the wrong approach here?
As an example (real life one that I ran into), think of your navigation controller that might open and close new windows. It works fine as a regular Composer to start with, but what if you need another ViewModel to trigger that Composer fire and open a page? You have to create a queue in order to notify it. Now if you refresh the page you have multiple instances of listeners unless you handle complicated clean up routines. Vs instead I just use a ViewModel on top of my navigation and I can listen for a globalCommand:
//use by the navigation menu clicks @Command public void onNavigate(@BindingParam("page") String page) { //code to open the correct page } //called from external view models @GlobalCommand public void switchPage(@BindingParam("page") String page) { onNavigate(page); }
With a Composer handling this you'd need
@Subscribe("navigationQueue") public void switchPage(Event event) { //.... }
Bottom line is I don't see what advantage I get not using ViewModels for everything.
In general, I agree with you. However, in my current project, which uses the business portal layout, I have mixed the two. For the portal container itself, I am using a SelectorComposer, but for all the portal children components, I find it better to use the MVVM design pattern.
I chose not to go with MVVM for the portal container itself due to its heavy involvement with dynamically creating, updating, and destroying its child components. But, the MVVM pattern has proven highly efficient for its child components because their min and max view can avail themselves of a shared viewmodel. So, bottom line for me is, if the container is primarily dealing with the management of UI components, a composer makes a bit more sense, but if the UI component is primarily dealing with the presentation and updating of data, then the MVVM makes more sense.
@rdgrimes...but do you ever have to call your composer from a view model? That's what caused me to change things since the only way I know of to notify the composer from a VM is to have the composer listen on a queue... this creates headaches when dealing with making sure the listener is removed when not being used any more. If you have a composer with @Subscribe listening for an event... and you refresh the page, you'll have multiple instances of the listener created and it'll fire for as many times as you have instances. It can create some real issues. I hope this gets addressed in some future release if it all possible.
Have you tried specifying the scope, as in
@Subscribe(value = "navigationQueue", scope = EventQueues.SESSION)
I believe the default scope is desktop otherwise.
I really don't know if that will make the difference, but alternately you could subscribe to the queue, not by using the annotation, but through code that first checks to see if the composer is already subscribed to it.
Hi I have something same question forEach() with viewModel or Composer...http://www.zkoss.org/forum/listComment/21070-How-can-Use-View-Model-in-Window-rather-than-Apply
@rdgrimes
I had tried using Session, but still ended up with multiple instances created.
In regard to not using the annotation, you're right there are ways to do things via code, but then you do need more complex checks like you pointed out and this forum link posts out http://www.zkoss.org/forum/listComment/18752-Event-Queue-subscribed-more-than-once, but that's sort of my point, it's a lot more code for what I see is no gain if I just use a ViewModel instead?
I did read your comment "I chose not to go with MVVM for the portal container itself due to its heavy involvement with dynamically creating, updating, and destroying its child components." and that's interesting- you must know a lot more about what's going on 'under the hood' than I do since I wasn't aware of all that. However, I haven't really noticed any perceived slowness in the application just using ViewModels. (I'm definitely open for switching though if it's going to cause me real problems.)
Good discussion. Thanks for your input.
Thanks @rickcr
Regarding to original topic, I will not choose only MVC or MVVM in my app, it is really depends on different case in the app.
I agree with rdgrimes, for the entire site control, or very exquisite control , I will use MVC. I can management many detail.
but for a form base or showing tedious data, I will use MVVM, it helps me to skip writing many code.
and MVVM is also good for a project that want to isolate UI and Controller from direct code access, and make your programmer think with the view-state not UI(both advantage and disadvantage).
Hi Dennis
You mean to say it is ok to use both MVC and MVVM ? . In most of my examples, i manage to use MVVM, but only problem is there is no way to detach the modal window on MVVM. So i always mix MVVM and MVC to achieve the same.
You can see an example here
And how do you guys feel about (or what is your experience with) using ViewModel with a little bit of view knowledge i.e. wiring some components in afterCompose()? I know it breaks MVVM pattern but do you see place for it as well or is it pure evil?
Asked: 2012-11-15 14:01:50 +0800
Seen: 552 times
Last updated: Dec 07 '12