Communicating between MVC and MVVM patterns and between View Models

From Documentation
Redirect page

Redirect to:

Stop.png This article is out of date, please refer to http://books.zkoss.org/zkessentials-book/master/ for more up to date information.


Communication between the MVC, MVVM and view models sounds to be the most difficult task to perform, however, it is in fact very easy to do and extremely powerful. The first item of interest is dealing with communication between the MVC and MVVM.

Posting a command from the MVC to an MVVM view model

To offer communication there needs to be a way for the MVC pattern bound section of the application to pass a command to the binder which will in turn talk to all the view models and tell them to run a particular command. This is achieved by posting a global command and works in a much similar way to the normal command system.

The example below shows a function which was taken from our SelectorComposer (MVC pattern) and shows the issuing of a global command. In the product view upon clicking of the add button will result in the execution of said function.

@Listen("onAddProductOrder=#PrdoDiv #prodGrid row productOrder")
public void addProduct(Event fe) {

	if (!(fe.getTarget() instanceof ProductOrder)) {
		return;
	}

	ProductOrder po = (ProductOrder) fe.getTarget();

	try {
		UserUtils.getShoppingCart()
			.add(po.getProduct(), po.getQuantity());
	} catch (OverQuantityException e) {
		po.setError(e.getMessage());
	}

	BindUtils.postGlobalCommand(null, null, "updateShoppingCart", null);
}

Line 17 shows the function "BindUtils" and its function "postGlobalCommand" is used to post a command to the binder. In this case the first two strings take the name of the binder and the scope of said binder, in this case it is set to null to use the default. In most cases one would want to set this to null. Then the string name for the command is given along with a map of arguments to pass, in this case null as there are no arguments.

This globalCommand is then executed by the binder on any view model that has registered for it. In the case of this application the ShoppingCartViewModel needs to refresh the cart items when a product is added to a cart. Therefore a function is created in the ShoppingCartViewModel and registered as a global command, this function has the ability to do some processing and then notify the binder that the cartItems in that view have changed. The snippet below shows this in action.

public class ShoppingCartViewModel {
	
	...
	
	@GlobalCommand
	@NotifyChange("cartItems")
	public void updateShoppingCart() {
		//no post processing to be done
	}
}

This takes care of passing commmands from the MVC composer to MVVM view model, the next section discusses message passing between MVVM view models.

Communication between MVVM view models

Communication between view models can be done in the same way as communication between MVC and MVVM by using the BindUtils to publish a global command from Java code and having a function registered as a GlobalCommand in the other view model. However, it is also possible to add a global command into the zul file. For example for the shopping cart view when submitting the order it needs to tell the order view to update, in the order view one registers the following function to capture a global command:

@GlobalCommand
@NotifyChange("orders")
public void updateOrders() {
	//no post processing needed
}

This function will updated the orders and it has the option to do post processing if necessary. The main question is how to invoke this, it is possible to do so using the postGlobalCommand function of the BindUtils class, the call to do this would be as follows:

BindUtils.postGlobalCommand(null, null, "updateOrders", null);

However, an easier way is to place this command into the zul file, so the submit order button structure looks like this:

<button id="submitOrderBtn" label="submit"
	onClick="@command('submitOrder') @global-command('updateOrders')"
	disabled="@load(empty vm.cartItems)" />

Here one notices that as well as having an @command assigned to the onClick attribute, it now also has an @global-command, which is equivalent to the java function above this snippet. This is the easiest way of providing the command.

This is all one needs to know on sending messages between the MVC and view models. The next section deals with adding Hibernate and a database into the mix.



Last Update : 2022/01/19

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.