Given a spark view named SomeContainer.spark that uses a partial view this way:
<SomeContent param1 = "Model.SomeValue"/>
and given a partial view named SomeContent.spark that uses the parameter this way:
<div>${param1}</div>
How can I modify SomeContent.spark to declare param1 upfront. I want to do that for two reasons:
Readability: readers will know what the partial view depends on
To get intellisence for param1 in Visual Studio
I tried to simply declare the same <var> in SomeContent.spark but it fails at runtime indicating that that variable already exists.
I got the answer from the Spark group. In the partial you can declare a variable using the <default/> element:
<default param1="new List<string>()" type="List[[string]]"/>
Not only does it declare the parameter (with the advantages mentioned in my question) but it also gives it a default value which can be used to prevent the partial form getting a NullReferenceException...
Related
I am refactoring an MVC 3 application, and moved a set of similar items into a partial view so I can keep that template DRY. Since the pieces don't all have the exact same properties, I am creating anonymous types like this:
var model1 = new { Description = "description 1", Message = "message 1" }
and passing them to the partial view like so:
#Html.Partial("_Partial", model1)
The partial view is then attempting to render certain blocks based on existence of a specific property, i.e.
#if (Model.Description != null)
{
#Model.Description
}
My issue is that even though I can see and navigate the Model object in the watch window during execution, I get a RuntimeBinderException in the if test that states 'object' does not contain a definition for 'ShowApplied'. I can obtain the values through reflection by calling (Model.GetType().GetProperty("ShowApplied").GetValue(Model)), but would much rather use the format shown in my code sample. I have been unable to find a clean solution...
How can I pass an anonymously-typed object to a partial view and access its properties directly? I feel like there is something simple I'm missing...
Why am I able to see the Model properties while debugging, but not access them from code?
EDIT
I am specifying #model dynamic.
Using an interface requires creating non-anonymous types because, as this answer explains,
An anonymous type cannot be cast to any interface or type except for object.
Insights from the comments (thank you) imply I have 2 options, since (as the answer to the linked question points out),
Anonymous types are internal, so their properties can't be seen outside their defining assembly.
and therefore are inaccessible to the Razor binding engine.
Use #Html.DisplayFor("amount") and deal with not having IntelliSense, reference lookups, etc.
Create classes that implement a common interface and bind my partial view to that interface.
This is actually a follow up question to this. When is it better to use a partial view and when is it better to use a view helper?
View helpers
Are normally used if you need to add some repetitive/complex logic within the view. A good example of this are some of the already provided view helpers, such as the Zend\View\Helper\Url.
The Zend\View\Helper\Url is designed to abstract away the repetitive construction of URLs, which otherwise would be considerably messy (and error prone) to do each time you need a link.
echo $this->url('zfcadmin/admin', array('action' => 'index');
/** /admin/home **/
The great thing regarding all view helpers is the ability to provided varied data, to a simple API, and have the output be constructed and returned to the view without the view being aware of how the data was generated.
In the case of the URL view helper; There is complex interaction with the Router and it make sense for all of this to be completed in one place.
View Partials
Conversely, view partials are all about "injecting" HTML (or other view data) fragments into other templates. They reduce the need to repetitively write the same HTML structure where only some of the variables are different; Allowing you to create views scripts as reusable 'templates'.
The documentation states
The Partial view helper is used to render a specified template within its own variable scope. The primary use is for reusable template fragments with which you do not need to worry about variable name clashes
I would often use a view partial where there is a small block of HTML that should be reused either as as "widget" or something within a loop.
Note
As there is a clear distinction between what the view partials and view helpers are trying to accomplish, you will often use them in tandem to create your final output. For instance a view partial that you include with $this->partial('/module/foo/bar.phtml', array()); may actually use a view helper within the '/module/foo/bar.phtml (as it is also a view).
Note 2
Just to confuse you even more, when you use $this->partial(); in your view; You are actually using the built in partial view helper Zend/View/Helper/Partial
I'm using T4MVC in my MVC 5 website. In a view, I have something like:
#Html.Partial(MVC.Shared.Views.ViewNames.Foo, Model.FooBar)
The Foo view expects a certain type, which is defined with #model, but Model.FooBar might have a different type. This error is not detected until runtime.
Is there a way to use T4MVC to render the partial with a typed method, like we can use ActionLinks, maybe something like:
#Html.Partial(MVC.Shared.Views.Foo(Model.FooBar)) // Error: Foo() expects Argument of type ...
Short answer is that T4MVC currently doesn't support fully strong typing this scenario.
It's something that could conceivably be done, but it would present challenges. Specifically, T4MVC would need to parse the view to determine the model type. Currently, it never parses views, but only detects their existence.
I am developing an Ember app and it is really great. But I have a annoying problem I can not solve. I use routing in my app and two diffent controllers with their own views. If I try to use a binding property from the first controller to the second one, that property is not reflected in the second view. In a short way I have something like this:
router = Em.Router.extend({.....});
App = Em.Application.create({
Router: router,
FirstCtrl: Em.Controller.extend({x:'ABC'}),
FirstView: Em.View.extend({...}),
SecondCtrl: Em.Controller.extend({xBinding:'Em.App.router.firstCtrl.x', y:'123'}),
SecondView: Em.View.extend({...}),
});
App.initialize();
Em.App = App;
If in the template for the second view I have something like this:
Binding property: {{x}}
Property with no binding: {{y}}
'ABC' is not shown in the view but there is no such problem with '123'.
In my browser I can access that property from Javascript console with Em.App.router.firstCtrl.x but Em.App.router.secondCtrl.x returns undefined.
So, my question is Why can't I access that property? How should I write that binding?
Thanks in advance for your help
I don't think Em at the beginning of binding is required, Try this..
SecondCtrl: Em.Controller.extend({xBinding:'App.router.firstCtrl.x', y:'123'}),
Well summing up the comments:
All the controllers defined in ember must end with Controller while routing, for example if you call router.get('applicationController').connectOutlets('home') its corresponding controller shall be App.HomeController or App.homeController
while binding use 'App.router.yourController.yourProperty' instead of 'Em.App.router.yourController.yourProperty'
We can also use connectControllers in order access properties across controllers if you want to avoid global bindings
I'm pretty new to the Symfony Framework and currently searching for the Best-Practice way to pass Parameters from a search to the included partials.
Currently I'm checking for the Parameter in the executeSearch Method and then setting a variable that is available in the searchSuccess.php File.
In the searchSuccess.php File I'm simply passing the variable to the Partial in the include_partial Method in the array. I keep passing the variable around until I'm in the correct partial.
My Method seems to complicated and wrong, but it seems I can't access the sfRequest variables outside the executeSearch Method?
You can access the request object in any template by calling $sf_request.