Unobtrusive Javascript有三層含義:一是在HTML代碼中不會隨意的插入Javsscript代碼,只在標簽中加一些額外的屬性值,然后被引用的腳本文件識別和處理;二是通過腳本文件所增加的功能是一種漸進式的增強,當客戶端不支持或禁用了Javsscript時網頁所提供的功能仍然能夠實現,只是用戶體驗會降低;三是能夠兼容不同的瀏覽器。
啟用Unobtrusive Javascript的步驟:
1.在web.config文件中加入
<configuration>
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
2.在網頁中加入
<script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
使用Unobtrusive Ajax主要有兩個用途:做客戶端的輸入驗證和異步的表單提交。客戶端驗證基本上是自動的,不用做特別的處理。下面用一個例子重點說一下提交表單。
數據模型是這樣的:每個類別有很多屬性,屬性可以分組,屬性組可以嵌套。然后在網頁創建和編輯屬性組,示意圖如下:

這是我半年前寫的代碼:
$(this).find(".CreatePropertyGroup").click(function () {
$(".InputGroupName").hide();
var id = $(this).next().val();
var td = $(this).parent().parent();
$.post("/Category/CreatePropertyGroup", { parentId: id, name: $(this).prev().val() }, function () {
td.load("/Category/PropertyGroup", { "id": id, "resultType": "html" }, loadGroupReady);
});
});
$(this).find(".CreateProperty").click(function () {
$(".InputPropertyName").hide();
var id = $(this).next().val();
var name = $(this).parent().find(".PropertyName").val();
var type = $(this).parent().find("#PropertyDataType").val();
var unit = $(this).parent().find(".PropertyUnit").val();
var range = $(this).parent().find(".ValueRange").val();
var td = $(this).parent().parent();
$.post("/Category/CreateProperty", { groupId: id, name: name, type: type, unit: unit, range: range }, function () {
td.load("/Category/PropertyGroup", { "id": id, "resultType": "html" }, loadGroupReady);
});
});
完全使用jQuery獲取控件值和提交,可讀性和可維護性不是很好。現在改用Ajax.BeginForm之后,很大地簡化了編程:
<div class="InputGroupName" style="display: none">
@using (Ajax.BeginForm(new AjaxOptions { Url = Url.Action("CreatePropertyGroup"), UpdateTargetId = "PropertyGroup" }))
{
<span>屬性組名稱:</span>
<input name="name" class="GroupName" type="text" />
<input type="hidden" name="categoryId" value="@categoryId" />
<input type="hidden" name="path" value="@path" />
<input type="submit" value="確定" />
}
</div>
對於不使用的表單的,直接點鏈接的可以用Ajax.ActionLink:
<td>
@Ajax.ActionLink("刪除", "DeletePropertyGroup", new { categoryId = categoryId, path = path, name = property.Name },
new AjaxOptions
{
HttpMethod = "Post",
Url = Url.Action("DeletePropertyGroup", new { categoryId = categoryId, path = path, name = property.Name }),
Confirm = "確認要刪除 '" + property.Name + "' 及其所有屬性嗎?",
UpdateTargetId = "PropertyGroup"
})
</td>
最終運行后生成的代碼如下:
<form action="/Category/EditCategory/4-2-2" data-ajax="true" data-ajax-mode="replace"
data-ajax-update="#PropertyGroup" data-ajax-url="/Category/CreatePropertyGroup" id="form5" method="post">
<span>屬性組名稱:</span>
<input name="name" class="GroupName" type="text" />
<input type="hidden" name="categoryId" value="4-2" />
<input type="hidden" name="path" value="PG.Props.1.Props" />
<input type="submit" value="確定" />
</form>
<a data-ajax="true" data-ajax-confirm="確認要刪除 '外觀特征' 及其所有屬性嗎?" data-ajax-method="Post"
data-ajax-mode="replace" data-ajax-update="#PropertyGroup" data-ajax-url="/Category/DeletePropertyGroup?categoryId=4-2&path=PG.Props&name=%E5%A4%96%E8%A7%82%E7%89%B9%E5%BE%81"
href="/Category/DeletePropertyGroup?categoryId=4-2&path=PG.Props&name=%E5%A4%96%E8%A7%82%E7%89%B9%E5%BE%81">刪除</a>
可以看到魔力就在於以data-ajax開頭的一些屬性中,當Javascript被禁用后,表單仍能提交,鏈接也能點開,只不過不再是異步的了。
