-
FEATURED COMPONENTS
First time here? Check out the FAQ!
I'm currently modularizing a big chunk of code, and many of it is being put into separete VMs. So far, the last 4 submodules were easy: Take the code out, make the window, add the ViewModel attribute to the code and keep going.
But this time I'm being hit with the error in the title. I double checked that I had the variable, which is there, and triple checked the getter is there. Yet, I simply cannot use this new VM in the new window.
I decided, just to make sure I'm not overlooking something, to use ZK's @WireVariable instead of Spring's @Autowired. And yes: It worked. But why?
I've already checked the code and I can confirm that both the zul and my class are ok, but using a "component instead of a class" won't do for this specific window.
Just to be very sure I'm being understood:
I change
<div viewModel="@id('vm') @init(classComponent)">...</div>
to
<div viewModel="@id('vm') @init('whole.path.to.ClassComponent')">...</div>
also changing the appropiate binding from @Autowired to @WireVariable and magically(?) error's gone and component works.
I don't mind using ZK's bindings over Spring's, but most of out code uses Spring's and I'm pretty much cleaning code, so I'm trying to default to one notation.
In previews experiments I've found that all ViewModels I've worked on work with either 'style' so I'm positive they are pretty much interchangeable.
Not this window in particular, so... What could cause this? I have tried to replicate this error with no luck, and sadly I don't think I can reproduce it in a fiddle either. My best guess is that the zul page is being created before the getter in my component, which kind of breakes what I undesrtand of Spring.
Any idea will be much appreciated. Good day!
EDIT:
About said property:
The VM is a very simple class that loads text from our database into a popup window. It has only two properties (That we use in the front end): A list of Strings paragraphs
and a String title
. title
gets initialized at @Init, and the whole error says "Property title not found in org.zkoss.zul.Window".
I was aware that I wasn't using the VariableResolver, but the last windows I've done don't use it. I thought "huh, weird but ok" when I noticed they all were properly working without it and moved on. This one seems to require it, altought I'm not 100% sure as of why. I guess I need to check in detail what is going on in these zk files. One of these windows doesn't actually use any variables (It's all GUI and commands with no inputs or reads from the backend) so that one should be fine even without the VariableResolver as far as I understand, but the others I'm not so sure.
Again, I'm not really concerned. If they work they work and optimizing them isn't really my requirement but I'd like to document this behaviour in simple spanish for newer front ends that might come in the future.
I'll experiment some more and if the seniors don't like me mixing @Autowire and @WireVariable, I'll add the VariableResolver.
EDIT:
These are code snippets that represent my .zul file:
<zk>
<window viewModel="@id('vm') @init(documentWindow)">
<caption/>
<div>
<div class="document-title">
<label id="docTitle" value="@load(vm.documentTitle)"/>
</div>
<div class="document-paragraph" children="@load(vm.documentParagraphs)">
<template name="children" var="p">
<span>${p.text}</span>
</template>
</div>
</div>
</window>
</zk>
and my ViewModel:
@Component
public class DocumentWindow {
@Autowired
private ParagraphsRepository paragraphsRepository;
private String documentTitle; // this is the property that is "not found"
private List<Paragraphs> documentParagraphs;
@Init
public void init(@ExecutionArgParam("id") Integer docId, @ExecutionArgParam("docTitle") String documentTitle) {
this.documentTitle = documentTitle;
this.documentParagraphs = paragraphsRepository.findRelevantByDocId(docId);
}
public String getDocumentTitle() {
return this.documentTitle;
}
public List<Paragraphs> getDocumentParagraphs() {
return this.documentParagraphs;
}
}
There is more going on both files, but the error refers especifically to documentTitle,
so I used only the relevant code. Using this "template" so to speak, it throws the "Property not found" error, targeting documentTitle
as the property and org.zkoss.zul.Window
as the class it's missing from. If I change the way I bind the VM and use the whole class name (Changing to @WireVariable
), the code works as expected.
I'm aware of the lack of a VariableResolver
, but again I've use this exact same "template" with other windows and components without an issue.
This window is being created from another viewModel(s) using Executions.createComponent()
where I pass the parameters. So far, the only "logical" thing I have though might have happened is that the zul page loaded faster than the call to the bean. This because when setting a breakpoint at the first line of the @Init
method in debug, it throws the error before going into the VM. But that is a bit of a wild guess on my part. This doesn't explain why my few other popup windows work just fine with this "tempalte" with no VariableResolver
though.
Good day!
Thanks for your writing in patient. But you don't mention which property is not found. Is that property a spring bean? Based on your story, I still cannot image the whole picture. So I just give you my inference.
If you write this
<div viewModel="@id('vm') @init(classComponent)">...</div>
ZK will treat classComponent
as a variable name and resolve this variable as a key in scope attributes from small scope to larger one:
If the variable is a spring bean, you should add the resolver below, then zk can resolve it as a spring bean whose bean name is the variable name:
<?variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?>
If the ViewModel is a spring bean, then Spring @AutoWired
in the ViewModel can work correctly because Spring instantiate this ViewModel, spring can do the dependency injection.
If you write a full-qualified class name like:
<div viewModel="@id('vm') @init('whole.path.to.ClassComponent')">...
Then ZK will instantiate the class, so the ViewModel is not a spring bean. Therefore, Spring @AutoWired
doesn't work in the ViewModel. Only ZK's @WireVairable
can work. If you want to wire a spring-managed bean, you need a add a resolver in ViewModel:
@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
Property title not found in org.zkoss.zul.Window
This error message is quite unexpected to me because Window does have a property title. So I wonder what's the complete stack trace.
<window noattribute="a"/>
you will get
org.zkoss.zk.ui.metainfo.PropertyNotFoundException: Method setNoattribute not found for class org.zkoss.zul.Window
org.zkoss.zel.PropertyNotFoundException: Property 'abc' not found on type issue.ListGroupVM
According to your error message, it looks like case 2. but we usually don't use ZK component class as a ViewModel.
I'm quite confused with your case. The case2. means bind a non-existed property of a ViewModel. Do you mean you use a org.zkoss.zul.Window
as a ViewModel? If so, that's an invalid usage. When using Data binding, you should bind a ViewModel's property (POJO) to a component's attribute.
If the error is
org.zkoss.zel.PropertyNotFoundException: Property 'title' not found on type DocumentWindow
Then it's expected.
Because ZK loads a property by getter of DocumentWindow
, it contains getDocumentTitle()
instead of getTitle()
. The member field can be title
or mytitle
. So if you use vm.title
and no getTitle()
found in the ViewModel, ZK will throw Property 'title' not found
.
According to
it throws the "Property not found" error, targeting documentTitle as the property and org.zkoss.zul.Window as the class it's missing from.
In your code:
<window viewModel="@id('vm') @init(documentWindow)">
ZK will treat documentWindow
as a variable and try to resolve it from small scope to larger scope.
Hence, another possible cause is: there is a ZK Window
whose ID is documentWindow
. So ZK resolves it as a Window
component and failed to get documentTitle
from that Window
. Please also check this case.
Also, I unfortunately can't look into this much more as other responsabilities came in and the frontend team took over where I left. I might be able to poke around locally though. Something worth mentionting: I remember vaguely having a bit of an issue with scopes in this window. Ill try remember
Jtt ( 2021-08-17 23:25:29 +0800 )editAsked: 2021-07-14 05:22:03 +0800
Seen: 30 times
Last updated: Aug 10 '21
spring boot starter + ZK 9.5.1 issue on reload/reboot
bug with intboxes on mobile devices
zk keikai-how to add custom button/label to formulabar?
zk-keikai- update multiple cells parallel at same time asynchronously
zk-keikai-How to auto fit column width based on text
zk-keikai-ClipboardPateEvent-called twice
Reference a spring bean from VariableResolver