HomePage -
Tutorials -
Basic HTML Controls
Basic HTML Controls
bind-PROPERTY
to use the bind style your controls must inherit from
HtmlControl or
WebControl, and have the property
PROPERTY (camel-cased, such as
bind-myValue for property
MyValue)
<span runat="server" bind-visible="HasError"
bind-innerText="'Error Occurs! Reason: ' + #page.ErrorReason"/>
By default, the current template (page, user control, or master page) is the root object for your OGNL expression, thus the expression
"HasError" refers to
Page.HasError, and the
"User" would refer to
Page.User and so on . However, you may also use an OGNL variable as the root object. Predefined variables are: (prefix with
# when you use them)
bAttr-ATTRIBUTE
bind to
Control.Attributes, useful for plain HTML attributes that don't exist as properties on your control.
<span runat="server" bind-class="IsWeekend ? 'weekend': 'normalDay'"
bind-innerText="@System.DateTime@Now.ToShortDateString()"/>
Just use
${} to enclose your OGNL expressions, evaluation result is always converted to a string.
<h1>You're editing user profile for ${User.Name}:</h1>
Textbox and Checkbox support two-way bindings, for example:
<input runat="server" type="text" bind-value="User.Age"/>
<input runat="server" type="checkbox" bind-checked="User.IsActive"/>
<input runat="server" type="submit" ext-handler="SaveUser()"/>
<input runat="server" type="image" src="MyButton.gif" ext-handler="SaveUser()"/>
Before the page renders,
AqDWeb binds data from
User.Age and
User.IsActive to the textbox and checkbox. And after you click on the button, the User's
Age and
IsActive are updated to the values you submit, and then the
SaveUser event handler will deal with the User object (which has been updated) and return the URL of the new page to go (NULL means to stay current).
AqDWeb doesn't save the view state of the binding result, instead it relies on a very simple rewinding cycle to restore the original view when you post back. For example, reconsider the page code from the first tutorial:
protected override void OnDataBinding
(EventArgs e
) {
if (UserID !=
Guid.
Empty)
User =
AqDWeb.Services.
PersistentEntityBroker<User>.
FindByID(UserID
);
else
User =
new User
();
}
public virtual string SaveUser
() {
AqDWeb.Services.
PersistentEntityBroker<User>.
Persist(User
);
return null;
}
When you first request for this page, the cycle is simply:
*
OnDataBinding
=> Bind data from model (User) to view (your textbox and checkbox)
=> Render.
But when you post back, it cannot just fill your model (User) with the submitted data - the original view must be restored first (you will know the reason when your read the
Select control below), so the cycle becomes:
*
OnDataBinding (Rewinding to restore the original view)
=> Bind data from model to view
=> Fill your model (User) with the submitted data (
Age and
IsActive)
=> Invoke event handler (
SaveUser)
=>
OnDataBinding again to prepare the view after model is changed
=> Bind data from model to view
=> Render
Finally, consider what will happen if you do not save the User in
SaveUser: during the second
OnDataBinding, the User object is re-fetched from the database, and the data you submit will
disappear, just as same as when you forget to save data and then re-request the page.
Radio Button has the
bind-Checked two-way binding similar to that of checkbox', but you will find such a binding isn't very helpful to it. So I added a listener
ext-select:
<input runat="server" type="radio" name="OwnerSelection"
bind-value="Users[0].Name" bind-checked="Car.Owner == Users[0]"
ext-select="Car.Owner = Users[0]"/>
<input runat="server" type="radio" name="OwnerSelection"
bind-value="Users[1].Name" bind-checked="Car.Owner == Users[1]"
ext-select="Car.Owner = Users[1]"/>
<input runat="server" type="radio" name="OwnerSelection"
bind-value="Users[2].Name" bind-checked="Car.Owner == Users[2]"
ext-select="Car.Owner = Users[2]"/>
The
ext-select is evaluated when current radio button is selected at postback (by its current state, not by state change), and before the postback handler is invoked.
Just like Radio Button, but add more attributes in order to support options' data source:
<select runat="server" id="OwnerSelection"
ext-itemSource="Users" ext-itemVarName="usr"
ext-itemValue="#usr.ID" ext-itemText="#usr.Name"
ext-itemSelected="Car.Owner == #usr"
ext-selectItem="Car.Owner = #usr"/>
The above will walk through every items in
Page.Users, each of them is assigned to the OGNL variable whose name is specified by
ext-itemVarName (
usr, default is
option), and add an option with {text, value} = {
ext-itemText (
#usr.Name),
ext-itemValue (
#usr.ID)}, and evaluate
ext-itemSelected to decide if the current option should be selected; After postback it will then execute
ext-selectItem with
#usr set to the selected User.
PS: Notice the value of
ext-itemVarName is a plain variable name, not an OGNL expression.
At current stage (v0.9.1), all HTML controls have been completely supported. And soon there will be a custom
DataSource for data components such as
GridView.
However, you're not limited to these controls above -
AqDWeb uses a set of control extenders to perform data-binding for their corresponding controls, and you're free to write your own or even to override the existing ones, which will be detailed in next tutorials.
