Thinking about parameterised partial views in NHAML.
_ TextBox(“FirstName”, “Given Name”)
_ TextBox(“FirstName”)
_ TextBox
! (string key, string title=”Provide value:”)
= Html.LabelFor(key).Title(title + variableFromView)
= Html.TextBox(key)
the first line defines set of parameters for the partials. They can be used as regular variables on the partial view and do not intersect in any way with variables on the view. These are local variables only. So we can have integer key variable on the view with value 12345 and string key variable on the partial view with value “partial”. Of course the “partial” value should be the value used in the partial view. Additionally if there are no parameters passed defaults are used.
To satisfy the requirement #2 we must execute all the partial code in the same scope as the partial view itself. But this won’t satisfy requirement #1.
So at the moment, C# does not allow to implement this at the moment. And as a workaround for this we could discard requirement #2.
The requirements 3 and 4 should not be hard to do.
Possible implementation in meta-code for the NHAML generated code could look like:
So I would say we can pay the price of not being able to access global variables from partial for the sake of partial parameters.
Also I should mention that the way NHAML works now (joining all the partials into one scope) does not feel good/safe for me. I hit couple of issues with it previously that make my partials strongly bound to the view where they are used. So the partials should be isolated.
User perspective (view)
How I want to use the partials:_ TextBox(“FirstName”, “Given Name”)
_ TextBox(“FirstName”)
_ TextBox
User perspective (partial)
Define the _TextBox partial:! (string key, string title=”Provide value:”)
= Html.LabelFor(key).Title(title + variableFromView)
= Html.TextBox(key)
the first line defines set of parameters for the partials. They can be used as regular variables on the partial view and do not intersect in any way with variables on the view. These are local variables only. So we can have integer key variable on the view with value 12345 and string key variable on the partial view with value “partial”. Of course the “partial” value should be the value used in the partial view. Additionally if there are no parameters passed defaults are used.
Requirements
- View overrides variables used in outer scope.
- View can access outer-scope variables [POTENTIALLY SHOULD AVOID].
- Parameter values have default value if not specified in the actual list of parameters.
- Parameter can define a default value which will be used if no value has been provided.
Implementation thoughts
To satisfy requirements #1, it seems the partial view should be isolated from the rest of the view processing to be able to handle local variables (In C# it is impossible to have variable with the same name in one method). This behaviour is totally different from the way NHAML works now. Currently any view, partial, partial of partial (of partial…) are executed in one, single scope; generally, sharing all the variables.To satisfy the requirement #2 we must execute all the partial code in the same scope as the partial view itself. But this won’t satisfy requirement #1.
So at the moment, C# does not allow to implement this at the moment. And as a workaround for this we could discard requirement #2.
The requirements 3 and 4 should not be hard to do.
Possible implementation in meta-code for the NHAML generated code could look like:
// NHAML: _ TextBox("FirstName"), isolating the scope new NhamlGeneratedPartialTextBox(this).Render("FirstName", "Provide value:"); // NHAML: _ TextBox new NhamlGeneratedPartialTextBox(this).Render(default(string), "Provide value:");
So I would say we can pay the price of not being able to access global variables from partial for the sake of partial parameters.
Also I should mention that the way NHAML works now (joining all the partials into one scope) does not feel good/safe for me. I hit couple of issues with it previously that make my partials strongly bound to the view where they are used. So the partials should be isolated.