Need Delegate in Razor with two Parameters - razor

I have the following syntax in a .cshtml page:
#cell(<Class object>)
And is defined like this in the header:
Func<dynamic, object> cell =
#<........>;
How can I define the cell Func so that I can send it an int parameter, like this?
#cell(<Class object>, intNum)
Thanks

You have 2 ways:
first one, the clever way: make a class type that contains at least 2 properties, the original Class and the int number that you need. and then access them.
second one:
the proper way of razor delegate:
http://haacked.com/archive/2011/02/27/templated-razor-delegates.aspx
http://blogs.msdn.com/b/simonince/archive/2012/01/26/templated-razor-delegates-combined-with-partial-views.aspx
Use delegates is not necessary unless you need to pass html code to an htmlhelper extension.
Maybe you need to use a #helper function and conserve html inside a cshtml file.

Related

Add components based on string variables in Blazor

We're creating a dynamic page of components in Blazor. The intention is to have dynamic applets displayed on a page. The idea is that we have a list of strings which correspond to Component names. We read through the string list and for each one, instantiate a blazor component or render fragment. These are just simple components, no passed in parameters or the like. ie:
string[] componentsStrings = {"Component1", "Component2"};
Expected output:
<Component1 />
<Component2 />
We can't come up with a way to do this. It seems like a fairly standard thing to do, but perhaps not? Does anyone know if this is even possible?
You will have to programmatically create a component which adds your custom components on the page using RenderTreeBuilder.
Chris Sainty has a blog post on this which you can read here: https://chrissainty.com/building-components-via-rendertreebuilder/
Basically there is an override for BuildRenderTree in the ComponentBase class which can be used:
public class Menu : ComponentBase
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
base.BuildRenderTree(builder);
builder.OpenElement(0, "nav");
builder.AddAttribute(1, "class", "menu");
}
}
Here is another tutorial.
Some tips from here:
Place base.BuildRenderTree(builder); at the start of the
BuildRenderTree method , not at the end.
Always start with the value 0 for the sequence parameter.

Backbone toJSON not rendering

when I use Backbone toJSON method of the model like this:
this.$el.html(this.model.toJSON());
It doesn't render model into view root element ( more than one attribute ).
But when I get one property from the model, like this;
this.$el.html(this.model.get("city"));
It is rendered properly.
Also, when I use template in first case (toJSON) - it is rendered fine.
this.$el.html(this.template(this.model.toJSON());
Why is that ?
Thanks
this.$el.html(this.model.toJSON());
You're using the html method of jQuery, which expects a string (or a DOM element, or a jQuery element), to display a JSON object.
this.$el.html(this.template(this.model.toJSON());
Here you're using a template method which, I assume, is taking a JSON object to evaluate a template that will return you a string. The htmlmethod receives this string and displays it.
this.$el.html(JSON.stringify(this.model.toJSON()));
This would display the result of this.model.toJSON() (but won't do the same as using your template method).
So, basically this.template will be (in most of the cases) a compiled version of the html template which you have for the view.
It will have placeholders in it, and will take parameters with the same key as placeholders in the template. For example (Handlebars templates),
<section id="{{id}}">
<header>{{header_text}}</header>
</section>
Considering the above code as a template, when you compile and store it in this.template, it returns a function, which takes a json object as a parameter, so now this.template is a function.
You can call it like below,
var html_text = this.template({
id : "main_content",
header_text : "Hi Welcome !!"
});
this.$el.html(html_text);
After the execution, el's contents will be
<section id="main_content">
<header>Hi Welcome !!</header>
</section>
So when you do this.$el.html(this.template(this.model.toJSON());, it actually generates the required json parameter for the this.template method for you, hence works fine.
And as Loamhoof said, in this.$el.html(this.model.get("city")); you use the html method which will set the html content of the el based on the property value of the model.

Zend Framework a common file to put functions in that can be accessed from a view

I need to have a place to put some common functions that various view scripts will use such as creating some html by passing it a variable. I know about using helpers, but I want to be able to put many functions inside it not just one helper for each function.
Is it a plugin that I need to create?
thanks
A view helper is definitively the way to go. You can group a collection of similar or related functions using a simple design pattern for your view helper:
class App_View_Helper_Example extends Zend_View_Helper_Abstract
{
/**
* #param mixed|null $var
* #return App_View_Helper_Example
*/
public function example($var = null)
{
if ($var === null) {
return $this;
}
return $this->function1($var); // shortcut to method most used
}
public function function1($var)
{
return $this->view->escape($var);
}
public function function2($var1, $var2)
{
return $this->view->escape(sprintf('%s: %d', $var1, $var2));
}
// and so on...
}
This allows you to call your helper methods in your view like this:
$this->example($var);
$this->example()->function1($var);
$this->example()->function2($var1, $var2);
I used this approach for a Google Static Map helper which provides a centered()-method to display a map centered at a given location and a byMarkers()-method that displays a static map automatically centered and zoomed around a list of given markers.
The only problem you may encounter is keeping a state in your helper across different view scripts (e.g. when using layouts or partials) as the helper will be reconstructed with every single view script. To store state across these boundaries you'll have to resort to Zend_Registry or some static member field.
Hm, 'sounds a bit smelly'. What kind of functions would these be? If your design is ok, you shouldn't have a need for this kind of dustbin class. If it is really all about view then you should create view helpers, view partials or partial loops!
Sounds like what you want is the partial helper
If you don't want to use helpers (including the partial helper) you might as well just create some global functions, stick them in some file, and include it from your bootstrap file.
If you don't want a 'bunch of helpers' (which isnt really all that bad, as other posters have suggested), you can extend Zend_View, add the member methods, then set the Viewrenderer to your extended View.
http://framework.zend.com/manual/en/zend.controller.actionhelpers.html#zend.controller.actionhelpers.viewrenderer
Thank you all for the suggestions.
I discovered that you can use a view helper (like Stefan said) to store more functions by just returning $this from it like :
class Zend_View_Helper_FormVars
{
public function formVars(){
return $this;
}
public function openFormFieldGroup($name=''){
$html='';
$html.='<div id="formFldGrpWrapper">';
$html.='<div id="formFldGrpName"><b>'.$name.'</b></div>';
return $html;
}
}
Now in my view script I can use it like this:
$formVars=$this->formVars();
$html.=$formVars->openFormFieldGroup('General');
But I'm also interested in what Justin stated that I can have a common extended view helper?
That all my views or controllers can access for doing repetative tasks like some html divs/styles, etc.... How would I go about getting that set up?
thanks.
But I'm also interested in what Justin stated that I can have a common extended view helper? That all my views or controllers can access for doing repetative tasks like some html divs/styles, etc.... How would I go about getting that set up?
In the answers you ask this additional question. My answer deals with that too.
First you need to ask yourselves why you want to have multiple helper functions in one class
One reason is that you saves you extra classes and file includes. How could you do so?
If they are related you can put them into one view helper. But don't do things like
$this->htmlWrapper()->wrapParapgraph()->wrapContentBox()
->translateFromTo('NL', 'EN');
translateFromTo(…) has nothing to with html-wrapping.
If you want to optimize your includes, you can put you common helper code into a derived View-class:
class MyView extends Zend_View
{
function wrapParagraph() {}
function otherFunction() {}
}
This option is also mentioned in the zend framework guide as a means of optimization.
Please note that view helper reusability isn't affected by the choice to create view helpers as separate classes. You automatically get access to the current view oject if your helper extends Zend_View_Helper_Abstract.
class My_View_Helper extends Zend_View_Helper_Abstract
{
function wrapParagraph($content) {
// do something …
return $this->someOtherViewHelper();
}
}
Further you wrote
$formVars=$this->formVars();
This doesn't make sense actualy, since Zend_View registers only one view helper per view isntance.
$formVars=$this->formVars();
$formVars->doOneThing();
$formVars->doSecondThing();
is equivalent to
$this->formVars()->doOneThing();
$this->formVars()->doSecondThing();
The Singleton aspect has a severe impact on the way you design view helpers as you see.

Pass HTML from controller to view

I've made a structure to retrieve from database, based on the role given, to return menu items.
Now, I need to make a recursive method to render this HTML in the controller and pass this HTML to view. But i just don't know how to write native HTML in the controller.
Any suggestions?
The controller should not handle any of the HTML at all. That's what the view in MVC is for. Your controller should pass a data structure from the model, and the view should render that data structure as HTML.
Easier than you might think:
Controller:
ViewData["html"] = #"<a href='http://www.stackoverflow.com'>Stack Overflow</a>";
View:
<%= ViewData["html"] %>
I do agree this isn't the best method. I would suggest you write the html markup in your view and substitute the values from your model instead.
e.g.
Controller:
ViewData["Title"] = "Stack Overflow";
ViewData["Url"] = #"http://www.stackoverflow.com";
View:
<a href="<%=Html.Encode( ViewData["Url"] )%>">
<%=Html.Encode( ViewData["Title"] )%></a>
If you have to create many, you could use a partial view / user control to encapsulate the common markup.
It's definitely not the idea of MVC (or whatever you're doing) to render HTML in the Controller. HTML has to be handled in the view. What if you want to provide an alternative UI (e.g. Windows Application)? HTML does not really fit into an WinApp.
You can use an HTML helper to create the HTML. For example, we have a Menu system that is very complex, so we create an HtmlHelper extension. Here's a simple html extension (I use TagBuilders to make the HTML easier ... very handy when you have lots of nested tags).
public static String MyNewExtension(this HtmlHelper html, String extraVariable)
{
if (html == null)
{
throw new ArgumentNullException("html");
}
TagBuilder h1Tag = newTagBuilder("h1");
h1Tag.InnerHtml = extraVariable;
return h1Tag.ToString();
}

ASP.Net MVC: How to dynamically generate a meta tag based on the content of the url?

Here is the idea:
When the user wants to see /controller/action, then I want the page to have a "robots" meta tag with its value set to "all".
When the user wants to see /controller/action?sort=hot&page=2 (i.e. it has a query string), then I want the page to have a "robots" meta tag with its value set to "noindex".
Of course this is just an example and it could be another tag for the existence of this question.
At what stage in the MVC architecture could I place a hook so that the view generates the tag I want in the master page?
I do something similar for generating page titles and it works well. Put your tag in your masterpage as normal:
<%= Html.Encode(ViewData["Title"]) %>
Then subclass ActionFilterAttribute and override OnActionExecuting. From there you get access to the controller context and can set your viewdata to whatever you want.
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.Controller.ViewData["title"] = "whatever";
}
last step is to put Attribute your controllers that you want to use the filter context. You can inherit from a base controller if you want to add the attribute to all classes. There are also overloads if you want to pass parameters. In my app. I actually pass the page title.
Hope that helps.