4

When I render a view from a controller, variables passed to the view are in the scope of all templates rendered in the view, including templates nested several levels deep.

However, when I render a template from a controller (as in ajax style), only the initial template seems to have access to the variables, and nested template calls do not share this information. Example:

Views & Templates:
a.gsp
_b.gsp
_c.gsp
_one.gsp
_two.gsp
_three.gsp

//PasserController.groovy
class PasserController{
    def v = {
       render(view:"a", model:[time:System.currentTimeMillis()])
    }

    def t = {
        render(template:"one", model:[time:System.currentTimeMillis()])
    }
}    

//a.gsp
A Time is: ${time}<br />
<g:render template="b" />

//_b.gsp
B Time is: ${time}<br />
<g:render template="c" />

//_c.gsp
C Time is: ${time}<br />

//_one.gsp
One Time is: ${time}<br />
<g:render template="two" />

//_two.gsp
Two Time is: ${time}<br />
<g:render template="three" />

//_three.gsp
Three Time is: ${time}<br />

And the output is as follows:

For passer/v
A Time is: 1309188408223
B Time is: 1309188408223
C Time is: 1309188408223

and

For passer/t
One Time is: 1309188515894
Two Time is: 
Three Time is:

Can anyone explain to me why the apparent variable scope on a view is all sub-templates, including those nested inside other templates, but the scope on a template rendered directly is only that template and not the nested templates?

If this is on purpose (not a bug), its kind of sad because the requirement for this site is very complex, and taglibs are not really a useful option in this case. Also, since this is ajax, we have many actions which will need to render templates instead of views and those resulting templates can be quite complex and nested in structure. Is there another way to do this?

Thanks for your time and help, I realize it was a long post!

Quad64Bit
  • 568
  • 7
  • 16
  • @Quad64bBit: excuse me, but I still don't understand why you can't use view? If you worry about the ajax response(maybe intepreted as HTTP response with view), you can render manually. – Hoàng Long Jun 27 '11 at 15:59
  • 1
    but why not just pass this arguments as parameters? `` – Igor Artamonov Jun 27 '11 at 17:55
  • Thanks for the feedback, but I don't have control over whether or not the we use ajax for this. The variable that will be passed is not a simple string, it is a collection of objects and as far as I can tell, I can't pass that in a tag. Am I misinformed as to how ajax swaps out a portion of a page? Can I replace the contents of a div with a view vs a template? – Quad64Bit Jun 27 '11 at 18:15
  • @splix Ah yes! You are in fact correct. Please submit your comment as an answer so I can upvote it! I didn't realize I could pass maps in the – Quad64Bit Jun 28 '11 at 18:18

1 Answers1

7

You can pass this arguments as parameters: <g:render template="two" model="${[time: time]}"/>

Igor Artamonov
  • 35,450
  • 10
  • 82
  • 113
  • Thanks! I didn't realize that you could pass complex collections using the gsp tag in the same way you can with groovy methods/closures. Thanks! – Quad64Bit Jun 30 '11 at 12:22