简体   繁体   English

如何从复合组件外部设置复合组件的值

[英]How to set the value of a composite component from outside the composite component

So, I have a composite component. 因此,我有一个复合组件。 Inside it, I have a regular text input, using one of the composite component's attributes for a value. 在其中,我有一个常规的文本输入,使用复合组件的属性之一作为值。

<h:inputTextarea id="#{cc.attrs.id}Text" value="#{cc.attrs.value}">
    <f:ajax event="blur" listener="#{someBean.onBlur}" />
</h:inputTextarea>

As you can see, I have an event inside the text box. 如您所见,我在文本框中有一个事件。 This event opens a popup and populates it with the text on the composite control. 此事件将打开一个弹出窗口,并使用复合控件上的文本填充它。 It also saves a reference to the composite control that invoked it. 它还保存对调用它的复合控件的引用。 Let me show you: 让我演示给你看:

public void onBlur(AjaxBehaviorEvent event) {
    this.fieldReference = (UIInput) event.getSource();

    this.formula = this.fieldReference.getValueExpression("value")
            .getValue(FacesContext.getCurrentInstance().getELContext())
            .toString();

    this.displayPopup = true;
}

So far, so good. 到现在为止还挺好。 Now, the problem comes when I try to close the popup and then update the value on the composite component with the one entered on the popup. 现在,当我尝试关闭弹出窗口,然后使用在弹出窗口中输入的值更新复合组件上的值时,问题就来了。 I try to do this: 我尝试这样做:

public void accept(ActionEvent event) {
    this.fieldReference
            .getValueExpression("value")
            .setValue(FacesContext.getCurrentInstance().getELContext(), this.formula);
    this.displayPopup = false;
}

When I try that, I get: 当我尝试这样做时,我得到:

javax.el.PropertyNotFoundException: //C:/myProject/Path/compositeComponentPage.xhtml at line 22 and column 183 value="#{cc.attrs.value}": Target Unreachable, identifier 'cc' resolved to null

Seems to me that the EL context on that request is different, and thus cannot resolve the variables in the composite component's expressions... but if I try to also store a reference to the ELContext object from the composite component's request (on the onBlur() method), then when I try to use it in accept() , I get: 在我看来,该请求上的EL上下文是不同的,因此无法解析复合组件表达式中的变量...但是,如果我尝试同时存储复合组件的请求中对ELContext对象的引用(在onBlur()方法),那么当我尝试在accept()使用它时,我得到:

javax.faces.event.AbortProcessingException: java.lang.IllegalStateException: Error the FacesContext is already released!

Using MyFaces 2.0.2 (the version that comes with WebSphere 8.5, I believe they modify it), and RichFaces 4.2.3. 使用MyFaces 2.0.2(WebSphere 8.5随附的版本,我相信他们会对其进行修改)和RichFaces 4.2.3。

Any ideas? 有任何想法吗?

Well, I seem to have found a solution. 好吧,我似乎找到了解决方案。 Looking around, I found this small piece of knowledge in a totally unrelated article on BalusC's blog : 环顾四周,我在BalusC博客上的一篇完全无关的文章中发现了这一小知识:

The backing component instance has basically a lifetime of exactly one HTTP request. 支持组件实例的生存期基本上只有一个HTTP请求。 This means that it's recreated on every single HTTP request, like as a request scoped managed bean. 这意味着它将在每个单个HTTP请求上重新创建,例如作为请求范围的托管Bean。

So, saving a reference to the component is a very bad thing to do. 因此,保存对组件的引用是一件非常不好的事情。 Instead, I saved the client ID of the component and looked it up when closing the popup, then used setValue , which previously hadn't worked. 相反,我保存了该组件的客户端ID,并在关闭弹出窗口时对其进行了查找,然后使用了setValue ,该功能以前无法使用。 Like this: 像这样:

public void onBlur(AjaxBehaviorEvent event) {
    UIInput component = (UIInput) evento.getSource();
    this.componentId = component.getClientId(FacesContext.getCurrentInstance());

    this.formula = component.getValueExpression("value")
        .getValue(FacesContext.getCurrentInstance().getELContext())
        .toString();

    this.displayPopup = true;
}

public void accept(ActionEvent evento) {
    UIInput component = (UIInput) FacesUtil.findComponent(this.componentId);
    component.setValue(this.formula);

    this.displayPopup = false;
}

So... I guess thanks, BalusC, you saved the day again!! 所以...我想谢谢BalusC,您又度过了美好的一天! :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM