Converter"

From Documentation
m ((via JWB))
 
(18 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 
{{ZKDevelopersReferencePageHeader}}
 
{{ZKDevelopersReferencePageHeader}}
 +
{{Deprecated | url=[http://books.zkoss.org/zk-mvvm-book/8.0/data_binding/converter.html zk-mvvm-book/8.0/data_binding/converter]|}}
 +
  
 
__TOC__
 
__TOC__
Line 7: Line 9:
  
 
= Implement a Converter=
 
= Implement a Converter=
Developers can create a custom converter by implementing the <javadoc> org.zkoss.bind.Converter</javadoc> interface. The method <tt> coerceToUi() </tt> is invoked when loading ViewModel's property to component and its return type should correspond to bound component attribute's value. The <tt> coerceToBean() </tt> is invoked when saving. If you only need to one way conversion, you can leave unused method empty.
+
Developers can create a custom converter by implementing the <javadoc> org.zkoss.bind.Converter</javadoc> interface. The method <code>coerceToUi()</code> is invoked when loading ViewModel's property to component and its return type should correspond to bound component attribute's value<ref>Since 6.0.1, a converter can return the <javadoc class="false"  method="IGNORED_VALUE">org.zkoss.bind.Converter</javadoc> to indicate that binder should ignore to load the value to component. It is useful if you want to do some extra method call on a component after a command or a value change notification</ref>. The <code>coerceToBean()</code> is invoked when saving. If you only need to one way conversion, you can leave unused method empty.
 +
 
 +
<blockquote>
 +
----
 +
<references/>
 +
</blockquote>
  
The following is how built-in converter 'formatedDate' implement.
+
The following is how built-in converter 'formattedDate' implement.
  
<source lang="java" high="11">
+
<source lang="java" highlight="11">
  
public class DateFormatConverter implements Converter {
+
public class MyDateFormatConverter implements Converter {
 
/**
 
/**
 
* Convert Date to String.
 
* Convert Date to String.
Line 49: Line 56:
  
 
</source>
 
</source>
* We retrieve "format" parameter's value  by <tt> ctx.getConverterArg("format") </tt>. This allows you to pass in arbitrary parameters.
+
* We retrieve "format" parameter's value  by <code>ctx.getConverterArg("format")</code>. This allows you to pass in arbitrary parameters.
  
  
According to above code, we can pass a "format" parameter to 'formatedDate' converter.
+
According to above code, we can pass a "format" parameter to 'formattedDate' converter.
  
 
<source lang="xml">
 
<source lang="xml">
  
<label value="@load(item.creationDate) @converter('formatedDate', format='yyyy/MM/dd')"/>
+
<label value="@load(item.creationDate) @converter(vm.myConverter, format='yyyy/MM/dd')"/>
 
</source>
 
</source>
  
 
= Use Custom Converter =
 
= Use Custom Converter =
The most common way to apply a converter is to bind a component attribute to ViewModel's property which is a custom converter or you can specify custom converter's full-qualified class name.
+
The most common way to apply a converter is to bind a component attribute to '''ViewModel's property which is a custom converter''' or you can also specify custom ''' converter's full-qualified class name'''.
  
 
'''Return a converter as a property'''
 
'''Return a converter as a property'''
Line 80: Line 87:
 
<label value="@load(vm.message) @converter(vm.myConverter)"/>
 
<label value="@load(vm.message) @converter(vm.myConverter)"/>
  
<label value="@load(vm.message) @converter('foo.MyConverter')"/>
+
<label value="@load(vm.message) @converter('com.foo.MyConverter')"/>
 
</source>
 
</source>
  
 
= Register Application Level Converters =
 
= Register Application Level Converters =
 +
 +
{{ZK EE}}
 
  Since 6.0.1
 
  Since 6.0.1
 +
 +
 
You can register application level converters<ref>Application level converter only has one instance and is shared between all binders.</ref> by setting library-property(''org.zkoss.bind.appConverters'') in zk.xml.
 
You can register application level converters<ref>Application level converter only has one instance and is shared between all binders.</ref> by setting library-property(''org.zkoss.bind.appConverters'') in zk.xml.
 
<source lang="xml">
 
<source lang="xml">
Line 104: Line 115:
  
 
= Use Built-in Converter =
 
= Use Built-in Converter =
ZK have provided some built-in converters that are commonly used. They can be used by <tt> '''@converter('converterName', parameterKey='value')''' </tt>. Currently, built-in converter we provide are : '''formatedNumber, formatedDate'''
+
ZK have provided some built-in application level converters that are commonly used. You can use them with name and parameters: <code>'''@converter('converterName', parameterKey='value')'''</code>.  
 +
 
 +
Currently, built-in converter we provide are :  
 +
* '''formattedNumber'''
 +
* '''formattedDate'''
  
 
<source lang="xml">
 
<source lang="xml">
Line 112: Line 127:
  
 
</source>
 
</source>
* You should specify number or date pattern in format parameter's value for formatedNumber converter or formatedDate converter.
+
* You should specify number or date pattern in format parameter's value for formattedNumber converter or formattedDate converter.
 +
 
 +
= Use Converter in Children Binding =
 +
 
 +
  since 6.0.1
 +
 
 +
Children-binding also supports converters, and it has a [[ZK Developer's Reference/MVVM/Data Binding/Children Binding |default converter]] (If user doesn't assign one) to convert user provided object into a <code>Collection</code> object. Users can use a customized converter like other binding. If you implement a converter for children binding, remember to return a <code>Collection</code> object in <code>coerceToUi( )</code>.
  
 +
<source lang="xml" highlight="1">
  
 +
<hlayout children="@init(vm.items) @converter(vm.itemConverter)">
 +
<template name="children">
 +
<label value="@load(each) "/>
 +
</template>
 +
</hlayout>
  
 +
</source>
  
 
=Version History=
 
=Version History=
{{LastUpdated}}
+
 
{| border='1px' | width="100%"
+
{| class='wikitable' | width="100%"
 
! Version !! Date !! Content
 
! Version !! Date !! Content
 
|-
 
|-
Line 125: Line 153:
 
| February 2012
 
| February 2012
 
| The MVVM was introduced.
 
| The MVVM was introduced.
 +
|-
 +
| 6.0.1
 +
| March 2012
 +
| Add section "Use Converter in Children Binding", "Register Application Level Converters"
 
|}
 
|}
  

Latest revision as of 07:35, 8 July 2022

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


Converter performs two way conversion between ViewModel's property and UI component attribute value. It converts data to component attribute when loading ViewModel's property to components and converts back when saving to ViewModel. It's quite common requirement to display data in different format in different context. Using converter developers can achieve this without actually changing the real data in a ViewModel.


Implement a Converter

Developers can create a custom converter by implementing the Converter interface. The method coerceToUi() is invoked when loading ViewModel's property to component and its return type should correspond to bound component attribute's value[1]. The coerceToBean() is invoked when saving. If you only need to one way conversion, you can leave unused method empty.


  1. Since 6.0.1, a converter can return the IGNORED_VALUE to indicate that binder should ignore to load the value to component. It is useful if you want to do some extra method call on a component after a command or a value change notification

The following is how built-in converter 'formattedDate' implement.

public class MyDateFormatConverter implements Converter {
	/**
	 * Convert Date to String.
	 * @param val date to be converted
	 * @param comp associated component
	 * @param ctx bind context for associate Binding and extra parameter (e.g. format)
	 * @return the converted String
	 */
	public Object coerceToUi(Object val, Component comp, BindContext ctx) {
		//user sets format in annotation of binding or args when calling binder.addPropertyBinding()  
		final String format = (String) ctx.getConverterArg("format");
		if(format==null) throw new NullPointerException("format attribute not found");
		final Date date = (Date) val;
		return date == null ? null : new SimpleDateFormat(format).format(date);
	}
	
	/**
	 * Convert String to Date.
	 * @param val date in string form
	 * @param comp associated component
	 * @param ctx bind context for associate Binding and extra parameter (e.g. format)
	 * @return the converted Date
	 */
	public Object coerceToBean(Object val, Component comp, BindContext ctx) {
		final String format = (String) ctx.getConverterArg("format");
		if(format==null) throw new NullPointerException("format attribute not found");
		final String date = (String) val;
		try {
			return date == null ? null : new SimpleDateFormat(format).parse(date);
		} catch (ParseException e) {
			throw UiException.Aide.wrap(e);
		}
	}
}
  • We retrieve "format" parameter's value by ctx.getConverterArg("format"). This allows you to pass in arbitrary parameters.


According to above code, we can pass a "format" parameter to 'formattedDate' converter.

<label value="@load(item.creationDate) @converter(vm.myConverter, format='yyyy/MM/dd')"/>

Use Custom Converter

The most common way to apply a converter is to bind a component attribute to ViewModel's property which is a custom converter or you can also specify custom converter's full-qualified class name.

Return a converter as a property

public class MyViewModel{
	private Converter MyConverter = new MyConverter();

	public Converter getMyConverter(){
		return myConverter;
	}
}


Example to use custom converter

<label value="@load(vm.message) @converter(vm.myConverter)"/>

<label value="@load(vm.message) @converter('com.foo.MyConverter')"/>

Register Application Level Converters

  • Available for ZK:
  • http://www.zkoss.org/product/zkhttp://www.zkoss.org/whyzk/zkeeVersion ee.png
Since 6.0.1


You can register application level converters[1] by setting library-property(org.zkoss.bind.appConverters) in zk.xml.

<library-property>
    <name>org.zkoss.bind.appConverters</name>
    <value>foo=my.FooConverter,bar=my.BarConverter</value>
</library-property>

Then use them by converter name.

<label value="@load(vm.message) @converter('foo')"/>
<label value="@load(vm.message) @converter('bar')"/>

  1. Application level converter only has one instance and is shared between all binders.

Use Built-in Converter

ZK have provided some built-in application level converters that are commonly used. You can use them with name and parameters: @converter('converterName', parameterKey='value').

Currently, built-in converter we provide are :

  • formattedNumber
  • formattedDate
	<label value="@load(item.price) @converter('formatedNumber', format='###,##0.00')"/>
	<label value="@load(item.creationDate) @converter('formatedDate', format='yyyy/MM/dd')"/>
  • You should specify number or date pattern in format parameter's value for formattedNumber converter or formattedDate converter.

Use Converter in Children Binding

 since 6.0.1

Children-binding also supports converters, and it has a default converter (If user doesn't assign one) to convert user provided object into a Collection object. Users can use a customized converter like other binding. If you implement a converter for children binding, remember to return a Collection object in coerceToUi( ).

			<hlayout children="@init(vm.items) @converter(vm.itemConverter)">
				<template name="children">
					<label value="@load(each) "/>
				</template>
			</hlayout>

Version History

Version Date Content
6.0.0 February 2012 The MVVM was introduced.
6.0.1 March 2012 Add section "Use Converter in Children Binding", "Register Application Level Converters"




Last Update : 2022/07/08

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