tags:

views:

73

answers:

4

I have a View which I call RenderPartial.

In the Partial usercontrol I set ViewData["IsTextAreaVisible"] = true;

In my View after the call to RenderPartial I check the value of ViewData["IsTextAreaVisible"].

Even though the usercontrol had set it, the View thinks that it is null.

Is this a bug or is there a better approach?

Thanks

+1  A: 

That is working as designed.

Each partial view gets it own copy of the view data so that any changes it makes don't taint the original. What you want to do, we've expressly prohibited.

Brad Wilson
What's the official recommendation then?
Jon
There is no official recommendation. For your given example, using CSS to hide things would be best. Making decisions about what's visible or not should be a model or controller concern, not a view concern, IMO.
Brad Wilson
I'm basically checking that server side value to say if visible ouput a link to a javascript file and initilise TinyMCE editors for them. I dont want to call tinyMCE.init if there are no textboxes.
Jon
You should be able to make that decision in the controller (or at least in the parent view)...
Brad Wilson
+1  A: 

I think that the RenderPartial method actually makes a new dictionary out of the object you pass it as ViewData. Since the dictionary is different, the original won't contain any new values you've added to it.

It seems to me though, that if you can calculate the value you are setting in the partial, you ought to also be able to calculate it in the parent view. You might want to think about reversing the calculation and perform it in the parent view and add it before calling the partial. You could always check if it is available in the partial and, if not set, recalculate as needed.

tvanfosson
A: 

Exchange of data between components of a view looks to me like a design fault. View (full or partial) are there just to passively and stupidly display the model state. All checks, calls and set up of values should be done in models/controllers. I would advice you to rethink you architecture. Even if it seems to you nice and suitable right now, there is a likelihood sooner or later you will have to redesign this piece of code.

User
A: 

Expanding on what Brad said, do it client side with JavaScript. Using JQuery you can find out if there are any visible textboxes on the page and init the client as so.

$(document).ready(function() {
  if ($("input[@type=text]:visible").length > 0) {
    // inject JS file and init tinyMCE.
    $.getScript('<%= ResolveUrl("~/Scripts/tinymce/tiny_mce.js")' %>, function() {
      // TODO: call tinyMCE's init function here
    });
  }
});

That will initialize it only if there are inputs that are visible.

See http://docs.jquery.com/Ajax/jQuery.getScript for restrictions on getScript

Edit: Edited to expand it based on Jon's comment. Note that I haven't run this revised edit in a browser so there may be a hiccup or two. Also, this should really be re-tagged with jQuery if you accept this solution.

andymeadows
Unfortunately that doesn't seem to work. I've looked in Firebug and the get seems to be working but it throws an error on tinymce.init. I think its because I am calling it in document.ready. I know there is an issue relating to this.
Jon
If the issue is it doesn't have time to load, why not call it with a delay to load. Can you clarify what the issue is?
andymeadows