KeyValueCoding is the mechanism by which templates link values of dynamic bindings
to their associated java class.
In most cases, what you will be linking to is a simple named field or method. But behind the scenes, more is going on. When you write out a dynamic binding in a template, say something like <wo:str value="$someName" />
, the template will attempt to dynamically resolve someName
against the java class in the following order, using the first found implemented method:
NGKeyValueCodingAdditions
invoke public Object valueForKeyPath( String )
with "someName" as a parameterNGKeyValueCoding
invoke public Object valueForKey( String )
with "someName" as a parametergetSomeName()
someName()
isSomeName()
_getSomeName()
_someName()
_isSomeName()
_someName
_isSomeName
someName
isSomeName
NGKeyValueCoding.UnknownKeyException
is thrown.This lookup is done by NGKeyValueCodingAdditions.Utility::valueForKeyPath( Object object, String key )
which is public API and you can use to perform a similar lookup.
👷TODO
Dynamic bindings can have multiple components, like method chaining in Java. And like in Java, components are separated by a period. When a binding has multiple components, we refer to them as KeyPaths
(while single component paths are usually referred to as keys
).
If you write <wo:str value="$company.manager.name" />
the object graph will be traversed through that path and the lookups specified above will be performed on the value returned by each component of the path to get the final value.
Nulls
in keyPathsIf any component of the keyPath returns null
, say, if you write company.manager.name
and manager
returns null, the entire keyPath will resolve to null instead of throwing a NullPointerException
like you might expect in Java.
It's like working in a language with a null safe navigation (elvis) operator and spell out the path as "company?.manager?.name", but in our case the operator is implicit.