2017-01-25 23 views
0

我想将值传递给托管bean。所以我有这样的托管bean:使用JSF自动设置托管bean变量的值

@ManagedBean(name = "mbWorkOrderController") 
@SessionScoped 
public class WorkOrderController { 

    // more attributes... 

    private WorkOrder workOrderCurrent; 

    // more code here... 

    public WorkOrder getWorkOrderCurrent() { 
     return workOrderCurrent; 
    } 

    public void setWorkOrderCurrent(WorkOrder workOrderCurrent) { 
     this.workOrderCurrent = workOrderCurrent; 
    } 
} 

它拥有自定义类型WorkOrder的参数workOrderCurrent。类别WorkOrder具有类型的属性applicant

目前我在我的inputtext里面使用placeholder向用户显示他需要在inputText内键入的内容。

<p:inputText id="applicant" 
    value="#{mbWorkOrderController.workOrderCurrent.applicant}" 
    required="true" maxlength="6" 
    placeholder="#{mbUserController.userLoggedIn.username}" /> 

我想要做的,是自动的mbUserController.userLoggedIn.username值传递给mbWorkOrderController.workOrderCurrent.applicant从我的形式完全删除inputTextapplicant

我试图用c:set

<c:set value="#{mbUserController.userLoggedIn.username}" target="#{mbWorkOrderController}" property="workOrderCurrent.applicant" /> 

但可惜的是,我得到一个javax.servlet.ServletException与消息:

类 'WorkOrderController' 没有财产 'workOrderCurrent.applicant'。

有没有人有建议?

回答

2

类'WorkOrderController'没有属性'workOrderCurrent.applicant'。

您的<c:set>语法不正确。

<c:set value="#{mbUserController.userLoggedIn.username}" 
     target="#{mbWorkOrderController}" 
     property="workOrderCurrent.applicant" /> 

你似乎认为的一部分。这在幕后

value="#{mbWorkOrderController.workOrderCurrent.applicant}" 

..works如下:

WorkOrderCurrent workOrderCurrent = mbWorkOrderController.getWorkOrderCurrent(); 
workOrderCurrent.setApplicant(applicant); 
mbWorkOrderController.setWorkOrderCurrent(workOrderCurrent); 

这是不正确的。它的工作原理在幕后如下:

mbWorkOrderController.getWorkOrderCurrent().setApplicant(applicant); 

正确<c:set>语法因此,如下图所示:

<c:set value="#{mbUserController.userLoggedIn.username}" 
     target="#{mbWorkOrderController.workOrderCurrent}" 
     property="applicant" /> 

那说,这一切是不是正确的方法来the concrete problem you actually tried to solve。您应该在模型本身中执行模型预填充。这可以通过使用@ManagedProperty引用另一个bean属性并使用@PostConstruct来基于它执行初始化来实现。

@ManagedBean(name = "mbWorkOrderController") 
@SessionScoped 
public class WorkOrderController { 

    @ManagedProperty("#{mbUserController.userLoggedIn}") 
    private User userLoggedIn; 

    @PostConstruct 
    public void init() { 
     workOrderCurrent.setApplicant(userLoggedIn.getUsername()); 
    } 

    // ... 
} 
+0

非常感谢您广泛的职位!这解决了我的问题。 – antarkt1s

0

也许你可以解释一下上下文,但这是另一种解决方案。如果您要从其他页面导航,则可以在URL中传递WorkOrder中的某个标识,如http://host:port/context/page.xhtml?workOrderId=1

然后,您可以设置标识符在这样的托管bean:

<h:html> 
    <f:viewParam name="workOrderId" value="#{mbWorkOrderController.id}"/> 
</h:html> 

您将有一个新的属性添加到你的bean:

public class WorkOrderController { 
    private long id; 
    public long getId() { return id; } 
    public void setId(long id) { this.id = id; } 

    // ... 
} 

,然后在后财产已由JSF设置,您可以在生命周期事件中找到工作订单:

<h:html> 
    <f:viewParam name="workOrderId" value="#{mbWorkOrderController.id}"/> 
    <f:event type="preRenderView" listener="#{mbWorkOrderController.findWorkOrder()}"/> 
</h:html> 

public class WorkOrderController { 
    private long id; 
    public long getId() { return id; } 
    public void setId(long id) { this.id = id; } 

    public void findWorkOrder() { 
     this.workOrderCurrent = null /* some way of finding the work order */ 
    } 

    // ... 
} 

此策略具有a让您拥有可收藏的网址的好处。