質問

I am new to Dojo (and in fact all front end programming, I have been working on server side for years in Java and C#). I am currently working with Java Server Faces (JSF) 2.1 and trying to put together a simple demo using JSF and Dojo Grid (dgrid) with Dojo 1.8. I have a example from the dgrid site that shows how to work with making a Gantt chart, but this example doesn't show how to extract JSON data from an application server and feed it to the function. The problem is that I am having a hard time wrapping my brain around ARM - I am hoping some experience out there can help reduce some of my pain. Here is some code:

This is in the html file I created, when loading, it just creates the gantt:

<script>
    require([ "gantt/GanttGrid", "gantt/data" ], function(GanttGrid, data){
        // Instantiate the GanttGrid using predefined test data
        new GanttGrid({
            store: data,
            query: {
                // Only tasks with no parent task should be displayed in the root of the chart
                parent: undefined
            }
        }, "gantt");
    });
</script>

"data" is pulled from a separate js file and is just JSON data that is slurped into the DOJO's Memory object:

define(["dojo/store/Memory"],function(Memory){
return new Memory({data:[
        {name: "100", start: 1327900000000, end: 1328300000000, completed: 0.9, id: 1},
        {name: "101", start: 1328100000000, end: 1328400000000, completed: 0.9, id: 2},
        {name: "102", start: 1329100000000, end: 1329800000000, completed: 0.4, dependencies:[1], id: 3},
        {name: "103", start: 1328400000000, end: 1328900000000, completed: 0.4, dependencies:[1], id: 4},
        {name: "104", start: 1329000000000, end: 1329800000000, completed: 0.4, id: 5},
        {name: "105", start: 1329000000000, end: 1329400000000, completed: 0.4, id: 6},
        {name: "106", start: 1329400000000, end: 1329800000000, completed: 0.4, id: 7}
    ],
    getChildren: function(parent, options){
        return this.query({parent: parent.id}, options);
    },
    mayHaveChildren: function(parent){
        return parent.hasChildren;
    }
});});

Now, what I want is to be able to call a JSF Managed Bean's method that will execute some logic on the backend and then return JSON data that I can add to DOJO's Memory store and pass that into GanttGrid, however, I can't seem to figure out how to pull that off with an ajax request.

Here is what I have in my XHTML file that successfully gets the data from the bean and displays it on the screen:

<fieldset>
    <h:form id="schedulerForm">
        <h:commandButton value="Execute Demo" id="executeDemo">
            <f:ajax event="click" listener="#{autoScheduler.executeDemo}" render="result"  />
        </h:commandButton>
        <p />
        <h:outputText id="result" value="#{autoScheduler.result}"  />
    </h:form>
</fieldset>

What i would like is to capture the result of executeDemo on the JSF bean to pass to a function that creates the GanttGrid. I have tried using the "on" functionality in DOJO, but that only allows me to capture the button click (from what i can tell) ... I can't figure a way to know when the execution is complete so that I can get the data from the bean and create a chart. The biggest problems is that I can't figure out how I might call JSF beans with the DOJO request module.

I hope someone knows an easy way to accomplish this. Thanks ahead of time for any help! Please do let me know if you need more info... I tried to include all the relevant code.

-Paul

役に立ちましたか?

解決

Well, JSF does not allow calling arbitrary Java code using JavaScript. It only allows you to trigger requests that call the bean methods it would call if a JSF component had triggered it (say, a commandButton were clicked, for example), using the jsf.ajax Javascript object. Check out the API here.

This API is very tight to the View code, it triggers a request and also the updates to parts of the view.

For example, here is a commandButton very similar to yours, but using vanilla JavaScript to trigger the AJAX instead of the f:ajax tag and with a small bit of additional JS code:

<h:commandButton value="Execute Demo" id="executeDemo"
  onclick="console.log('hey, I am an arbitrary JS code');
  jsf.ajax.request(this, event, {execute:'@this', render: 'result'});
  return false;" />

Additionally, while f:ajax does allow you to execute your JavaScript code when a request is complete, you really can't "call the java bean code" to get the data you want at this point. But you can put the data in the DOM using JSF Ajax, and get it from the DOM in your callback.

Here is an example to get you started, that gets data formatted in JSON:

A simple Bean method returning a string with a JSON encoded object:

public String getMyData() {
    return "{\"fruit\": \"banana\"}";
}

View code:

<fieldset>
    <h:form id="schedulerForm">
        <h:commandButton value="Execute Demo" id="executeDemo">
            <f:ajax event="click" listener="#{autoScheduler.executeDemo}"
               render="result myHiddenData" onevent="parseData()" />
        </h:commandButton>
        <p />
        <h:outputText id="result" value="#{autoScheduler.result}"  />
        <h:panelGroup id="myHiddenData" style="display: none">#{autoScheduler.myData}</h:panelGroup>
    </h:form>
    <script>
        function parseData(data){
            if (data.status == "success") {
                var myRawData = document.getElementById("schedulerForm:myHiddenData").innerHTML;
                var myJsonData = JSON.parse(myRawData);
                alert(myJsonData.fruit);
            }
        }
    </script>
</fieldset>

See also these related questions:

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top