Communication between ViewModel and Composer"

From Documentation
m ((via JWB))
 
(15 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
{{ZKDevelopersReferencePageHeader}}
 
{{ZKDevelopersReferencePageHeader}}
 +
{{Deprecated | url=[http://books.zkoss.org/zk-mvvm-book/8.0/advanced/communication_between_viewmodel_and_composer.html zk-mvvm-book/8.0/data_binding/advanced/communication_between_viewmodel_and_composer]|}}
  
{{Template:UnderConstruction}}
 
  
  
In order to understand the following paragraphs, you had better understand [[ZK Developer's Reference/MVVM/ViewModel/Commands#Global_Command | concept of global command]] and [[ZK Developer's Reference/MVVM/Data Binding/Global Command Binding| global command binding]] first.
+
To get an in-depth understanding of the following paragraphs, it is recommended that you have read and understood the [[ZK Developer's Reference/MVVM/ViewModel/Commands#Global_Command | concept of global command]] and [[ZK Developer's Reference/MVVM/Data Binding/Global Command Binding| global command binding]] prior reading this article.
  
The [[ZK Developer's Reference/MVVM/Data Binding/Global Command Binding#Usage | global command binding usage section]] demonstrates how to communicate between multiple ViewModels. We can also use the same mechanism to perform communication between a composer and a ViewModel, but usage is a little different.
+
The [[ZK Developer's Reference/MVVM/Data Binding/Global Command Binding#Usage | global command binding usage section]] demonstrates how you can communicate between multiple ViewModels. We can also use the same mechanism to perform communication between a composer and a ViewModel, but of course, usage is a little different.
  
 
=Posting a Command from a Composer to a ViewModel =
 
=Posting a Command from a Composer to a ViewModel =
  
We have already known that global command is triggered by [[ZK Developer's Reference/MVVM/Data Binding/Binder| binder sending events into event queue]]. Hence ViewModels with attached binderscan communicate each other by global command. But a composer doesn't have a binder to send a global command for it. Therefore, we provide a utility class, '''<javadoc> org.zkoss.bind.BindUtils </javadoc>''', that can do this job. You can use it in a composer.
+
We know that global command is triggered by [[ZK Developer's Reference/MVVM/Data Binding/Binder| binder sending events into event queue]], hence, ViewModels attached with binders are able to communicate with each other by global command. However, a composer doesn't have a binder to send a global command, therefore, we provide a utility class, '''<javadoc> org.zkoss.bind.BindUtils </javadoc>''', that can do this job. You can use it in a composer.
  
For example, after adding a product, you want to tell <tt> ShoppingCartViewModel </tt> to refresh shopping cart's items.
+
For example, after adding a product, you want to tell <code>ShoppingCartViewModel</code> to refresh shopping cart's items. Assuming that we do not change the default setting such that ShoppingCartViewModel's binder (receiver) subscribes to the default event queue.
  
 
''' Send a global command in a composer (Sender)'''
 
''' Send a global command in a composer (Sender)'''
  
<source lang="java" high="8">
+
<source lang="java" highlight="8">
  
 
public class MyComposer extends SelectorComposer{
 
public class MyComposer extends SelectorComposer{
Line 30: Line 30:
 
</source>
 
</source>
  
* we use <tt> BindUtils.postGlobalCommand(String queueName, String queueScope, String cmdName, Map<java.lang.String,java.lang.Object> args) </tt> to post a command.  We leave first two arguments as "null" to use default queue name and default scope ('''desktop'''). The third arguments is '''global command's name'''. You can send extra data with a Map by the fourth argument.  
+
* we use <code>BindUtils.postGlobalCommand(String queueName, String queueScope, String cmdName, Map<java.lang.String,java.lang.Object> args)</code> to post a command.  We leave first two arguments as "null" to use default queue name and default scope ('''desktop'''). The third arguments is '''global command's name'''. You can send extra parameters with a Map by the fourth argument.  
  
 
* The specified global command is then executed by all ViewModel's binders that have subscribed to the event queue in the same (desktop) scope.  
 
* The specified global command is then executed by all ViewModel's binders that have subscribed to the event queue in the same (desktop) scope.  
  
  
In the ShoppingCartViewModel, we should declare a global command method named "updateShoppingCart" to receive this command request and refresh cart items. The code snippet below shows this.
+
In the <b>ShoppingCartViewModel</b>, we should declare a global command method named "updateShoppingCart" to receive this command request and refresh cart items. The code snippet below shows this.
  
 
'''Global command in a ViewModel (Receiver)'''
 
'''Global command in a ViewModel (Receiver)'''
  
<source lang="java" high="5,7">
+
<source lang="java" highlight="5,7">
 
public class ShoppingCartViewModel {
 
public class ShoppingCartViewModel {
 
 
Line 51: Line 51:
 
}
 
}
 
</source>
 
</source>
 +
 +
* As [[ZK Developer's Reference/MVVM/Data Binding/Binder|a binder subscribes to desktop scope event queue by default]], we only need to declare a global command.
 +
 +
* To receive parameters with global command, please refer to [[ZK Developer's Reference/MVVM/Advance/Parameters#A_Global_Command_Example]].
  
 
=Posting a Command from a ViewModel to a Composer =
 
=Posting a Command from a ViewModel to a Composer =
  
Because a ViewModel has a binder attached to it, triggering a global command doesn't need <javadoc> org.zkoss.bind.BindUtils </javadoc>. We just can use global command binding.
+
As a ViewModel has a binder attached to it, triggering a global command doesn't need <javadoc> org.zkoss.bind.BindUtils </javadoc>, we can simply use global command binding.
  
<!-- default name of event queue subscribed by the binder is DEFAULT_QUEUE_NAME = "$ZKBIND_DEFQUE$" is too wired  
+
<!-- default name of event queue subscribed by the binder is DEFAULT_QUEUE_NAME = "$ZKBIND_DEFQUE$" which is too wired  
 
We specified another queue name.
 
We specified another queue name.
 
-->
 
-->
  
Assume that we want to inform a composer to update shopping cart's items.
+
Assuming that we want to inform a composer to update shopping cart's items.
  
 
'''Bind global command in a ZUL (Sender) '''
 
'''Bind global command in a ZUL (Sender) '''
Line 73: Line 77:
  
 
</source>
 
</source>
 +
* We set the queue name as 'myqueue' in which the binder publishes to.
  
 +
As mentioned earlier, global command is sent by event queue, the composer (receiver) should subscribe to the same scope event queue to receive this global command.
  
As we mentioned before, global command is sent by event queue, the composer (receiver) should subscribe to the same scope event queue to receive this global command.
+
'''To subscribe global command (Receiver) to the event queue'''
  
'''Subscribe to the event queue for the global command (Receiver)'''
+
<source lang="java" highlight="3">
 
 
<source lang="java" high="3">
 
  
 
public class MyComposesr extends SelectorComposer<Component>{
 
public class MyComposesr extends SelectorComposer<Component>{
Line 94: Line 98:
  
 
</source>
 
</source>
* For <tt> @Subscribe </tt>, please refer to [[ZK Developer's Reference/MVC/Controller/Subscribe to EventQueues]].
+
 
* To subscribe a event queue by method call, please refer to [[ZK Developer's Reference/Event Handling/Event Queues#Subscribe_to_an_Event_Queue]]
+
* Subscribe to a queue named 'myqueue' because previous binder publishes to this queue.
 +
* For <code>@Subscribe</code>, please refer to [[ZK Developer's Reference/MVC/Controller/Subscribe to EventQueues]].
 +
* To subscribe an event queue by method call, please refer to [[ZK Developer's Reference/Event Handling/Event Queues#Subscribe_to_an_Event_Queue]]
  
 
=Version History=
 
=Version History=
{{LastUpdated}}
+
 
{| border='1px' | width="100%"
+
{| class='wikitable' | width="100%"
 
! Version !! Date !! Content
 
! Version !! Date !! Content
 
|-
 
|-

Latest revision as of 07:35, 8 July 2022


DocumentationZK Developer's ReferenceMVVMAdvancedCommunication between ViewModel and Composer
Communication between ViewModel and Composer


Stop.png This article is out of date, please refer to zk-mvvm-book/8.0/data_binding/advanced/communication_between_viewmodel_and_composer for more up to date information.


To get an in-depth understanding of the following paragraphs, it is recommended that you have read and understood the concept of global command and global command binding prior reading this article.

The global command binding usage section demonstrates how you can communicate between multiple ViewModels. We can also use the same mechanism to perform communication between a composer and a ViewModel, but of course, usage is a little different.

Posting a Command from a Composer to a ViewModel

We know that global command is triggered by binder sending events into event queue, hence, ViewModels attached with binders are able to communicate with each other by global command. However, a composer doesn't have a binder to send a global command, therefore, we provide a utility class, BindUtils, that can do this job. You can use it in a composer.

For example, after adding a product, you want to tell ShoppingCartViewModel to refresh shopping cart's items. Assuming that we do not change the default setting such that ShoppingCartViewModel's binder (receiver) subscribes to the default event queue.

Send a global command in a composer (Sender)

public class MyComposer extends SelectorComposer{

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

		//business logic of adding a product

		BindUtils.postGlobalCommand(null, null, "updateShoppingCart", null);
	}
}
  • we use BindUtils.postGlobalCommand(String queueName, String queueScope, String cmdName, Map<java.lang.String,java.lang.Object> args) to post a command. We leave first two arguments as "null" to use default queue name and default scope (desktop). The third arguments is global command's name. You can send extra parameters with a Map by the fourth argument.
  • The specified global command is then executed by all ViewModel's binders that have subscribed to the event queue in the same (desktop) scope.


In the ShoppingCartViewModel, we should declare a global command method named "updateShoppingCart" to receive this command request and refresh cart items. The code snippet below shows this.

Global command in a ViewModel (Receiver)

public class ShoppingCartViewModel {
	
	...
	
	@GlobalCommand
	@NotifyChange("cartItems")
	public void updateShoppingCart() {
		//update shopping cart
	}
}

Posting a Command from a ViewModel to a Composer

As a ViewModel has a binder attached to it, triggering a global command doesn't need BindUtils, we can simply use global command binding.


Assuming that we want to inform a composer to update shopping cart's items.

Bind global command in a ZUL (Sender)

 <window apply="org.zkoss.bind.BindComposer" binder="@init(queueName='myqueue')"
   viewModel="@id('vm') @init('example.MyViewModel')" >

    <button id="addProduct" label="Add" onClick="@global-command('updateShoppingCart')"/>
</window>
  • We set the queue name as 'myqueue' in which the binder publishes to.

As mentioned earlier, global command is sent by event queue, the composer (receiver) should subscribe to the same scope event queue to receive this global command.

To subscribe global command (Receiver) to the event queue

public class MyComposesr extends SelectorComposer<Component>{
	
	@Subscribe("myqueue")
	public void updateShoppingCart(Event evt){
		if(evt instanceof GlobalCommandEvent){
			if("updateShoppingCart".equals(((GlobalCommandEvent)evt).getCommand())){
				//update shopping cart's items
			}				
		}
	}
}

Version History

Version Date Content
6.0.0 May 2012 Supplement to advanced topic.




Last Update : 2022/07/08

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