JSF ViewScoped tutorial

User Rating: 4 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Inactive
 

JSF ViewScoped tutorial

The @ViewScoped has been introduced by JSF 2.0 specification. In a nutshell the data which is @ViewScoped will keep living as long as you don't navigate to another pagee to itself. The view scope is very convenient, since it allows the pattern of initializing data when you first access a page (via a non-faces request, which is typically a GET request) and then keep that data when you work on the page, doing postbacks, AJAX requests, etc.

 

Best practice

This scope is quite useful when working with tables in JSF where you interact (add/edit/delete) with components in the table. Namely, in JSF there is a rule that the data that was used to render the table must be the EXACT SAME data that is used after the postback when processing the components you interacted with. With the view scope this is trivial, but without it it's rather tricky.

In this example application we will show how to create a CRUD application based on @ViewScoped in as little as 1 page and 1 Backing Bean.
Create a New Dynamic Web Project, choosing the a Target Runtime which is compatible with JSF 2.0 (JBoss 6/7).
jsf viewscoped tutorial
Next, select into the Project Facets to use JSF 2.0 Facets.
jsf viewscoped tutorial
Now let's add an index.html page which contains all the rendering logic:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
    <style type="text/css">
         <!-- Omitted for brevity -->
        </style>
</h:head>
<h:body>

    <h2>View Scope</h2>

    <h:panelGroup rendered="#{empty viewManager.cacheList}">
        <p>No data inserted yet.</p>
    </h:panelGroup>
    <h:panelGroup rendered="#{!viewManager.edit}">
        <h3>Add Data</h3>
        <h:form>
            <p>Key:
                <h:inputText value="#{viewManager.item.key}" />
            </p>
            <p>Value:
                <h:inputText value="#{viewManager.item.value}" />
            </p>
            <p>
                <h:commandButton value="add" action="#{viewManager.add}" />
            </p>
        </h:form>
    </h:panelGroup>
    <h:panelGroup rendered="#{viewManager.edit}">
        <h3>Edit item #{viewManager.item.key}</h3>
        <h:form>
            <p>Key:
                <h:inputText value="#{viewManager.item.key}" />
            </p>
            <p>Value:
                <h:inputText value="#{viewManager.item.value}" />
            </p>
            <p>
                <h:commandButton value="save" action="#{viewManager.save}" />
            </p>
        </h:form>
    </h:panelGroup>
    <h:form rendered="#{not empty viewManager.cacheList}">
        <h:dataTable value="#{viewManager.cacheList}" var="item"
            styleClass="table" headerClass="table-header"
            rowClasses="table-odd-row,table-even-row">
            <h:column>
                <f:facet name="header">Key</f:facet>
                <h:outputText value="#{item.key}" />
            </h:column>
            <h:column>
                <f:facet name="header">Value</f:facet>
                <h:outputText value="#{item.value}" />
            </h:column>
                <h:column>
                    <h:commandButton value="edit" action="#{viewManager.edit(item)}" />
                </h:column>
                <h:column>
                    <h:commandButton value="delete"
                        action="#{viewManager.delete(item)}" />
                </h:column>
         
        </h:dataTable>

    </h:form>

</h:body>
</html>

The most interesting part is the method expression syntax:

<h:commandButton value="edit" action="#{viewManager.edit(item)}" />

This feature (requires an EL 2.2 capable container like JBoss 6/7) allows to pass parameter value in the method expression like this #{bean.method(param)}.  This in turn allows to get rid of the DataModel object which acts as a glue between the JSF page and the Managed Bean.

Here is the ViewManager Bean which is annotated as @ViewScoped
package com.sample.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import com.sample.model.Property;

@ManagedBean(name="viewManager")
@ViewScoped
public class ViewManager   implements Serializable{

    ArrayList<Property>   cacheList = new ArrayList ();
    private Property item = new Property();
    public ViewManager() {
    }
    
    private boolean edit;

    public void add() {
        cacheList.add(item);
        item = new Property();

    }

    public void edit(Property item) {
        this.item = item;
        edit = true;
    }

    public void save() {
        item = new Property();  
        edit = false;
    }

    public void delete(Property item) {
        cacheList.remove(item);
    }

    public List getCacheList() {
        return cacheList;
    }
    public Property getItem() {
        return item;
    }

    public boolean isEdit() {
        return edit;
    }
}

 

jsf @viewscoped tutorial
Download the code from here.
Thanks to Balusc for inspiring this article, by reading http://balusc.blogspot.it/2010/06/benefits-and-pitfalls-of-viewscoped.html