原文地址:http://www.dotnetexpertguide.com/2012/06/cascading-dropdown-knockoutjs-aspnet.html

  免责申明:本文为翻译,仅用于学习交流,版权归原作者所有 (Nandip Makwana)

  更多说明:本着自学加深记忆之目的翻译此文,不用于任何商业用途

 

  在这篇基础性文章中,我们将借助 knockoutjs和ASP.NET MVC的帮助来生成级联下拉框.虽然用ASP.NET来生成级联下拉框没什么大不了的,如果我们谷歌一下的话,会找到大量的解决方案和演示文章.但是在这里展示的是我们如何借助knockoutjs来创建自更新的UI(显然基于用户交互)而不用写每次都要生成UI和DOM元素的JavaScript代码的方法.稍后我们使用一些技术来生成保持UI频繁刷新的应用程序.从here下载示例.

 

  本文中,最初显示给用户的是国家下拉框,根据用户所选择的国家显示另外一个包含该国省份的下拉框.示例使用jQuery.getJSON来获取所选国家的省份列表.服务端将返回JSON格式的省份列表,例如 JavaScript 数组.

  

   

  

  

  knockoutjs的魔法

  正如我们先前提到的一样,即使不使用knockoutjs也能生成级联下拉框,但是那样的话就不得不循环省份列表且必须用JavaScript操作字符串来生成省份下拉框.在这样的情况下,数据源(省份列表)只基于一个因素来刷新(当国家改变的时候).思考这样一种情况,当数据源频繁地刷新和基于不只一个因素.在这种情况下,操作字符串来生成UI或DOM元素就必须非常小心.现在knockoutjs带来了解决方案!是的,代替操作字符串生成UI或DOM元素,我们通过knockoutjs来生成基于MVVM原则的view(UI)和model(数据源).以后不管数据源在什么时候刷新我们只需要更新下层的viewmodel,剩下的则由knockoutjs来操心,包括根据刷新数据来更新UI.

  下面是Home控制器和省份实体类的代码.

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Country = new SelectList(Country.GetCountryList(), "Code", "Name");

        return View();
    }

    public ActionResult GetStates(string id = "")
    {
        var stateList = State.GetStates()
            .Where(s => s.CountryCode.ToLower() == id.ToLower());

        return this.Json(stateList, JsonRequestBehavior.AllowGet);
    }
}

// State model class
// Property of State class is used to 
// bind view with knockoutjs viewmodel
public class State
{
    public string CountryCode { get; set; }
    public int StateId { get; set; }
    public string StateName { get; set; }
}

  index.chshtml代码像这样

<p>
<b>Select Country :</b> @Html.DropDownList("ddlCountry", ViewBag.Country as SelectList, "Select...", new { onchange = "FetchStates();" })
</p>

<p data-bind="visible: states().length > 0">
<b>Select State :</b> <select data-bind="options: states, optionsText: 'StateName', optionsValue: 'StateId', optionsCaption: 

'Choose...'"></select>
</p>

  在JavaScript中定义的viewmodel

function CascadingDDLViewModel() {
    this.states = ko.observableArray([]);
}

var objVM = new CascadingDDLViewModel();
ko.applyBindings(objVM);

  如上所示,我们可以通过键入ko.observableArray来创建states的view model属性.knockoutjs的Observable类型不管下层对象什么时候被更新都会自动地通知.在index.cshtml片段,我们使用这个有data-bind特性的states属性.在data-bind特性的帮助下,我们通过knockoutjs viewmodel绑定DOM元素的行为(不管是显示或者隐藏,更新选择下拉框等等).因此不管下层viewmodel什么时候更新,DOM元素也会同时自动地更新.

  当用户改变国家下拉框的时候,下面的JavaScript将被调用.我们使用jQuery.getJSON来获取省份列表并用服务器响应来更新下层viewmodel.大功告成;由knockoutjs来刷新省份下拉框我们不需要循环省份列表和操作JavaScript字符串来重新生成下拉框.

function FetchStates() {
    var countryCode = $("#ddlCountry").val();
    $.getJSON("/Home/GetStates/" + countryCode, null, function (data) {
        objVM.states(data);
    });
}

  本文演示了如何使用knockoutjs和ASP.NET MVC来创建UI保持频繁刷新却不用烦恼于使用JavaScript操作字符串来重新生成UI的应用程序.

  本文示例代码从here下载.

  

 posted on 2012-06-25 16:56  Walking Dead  阅读(395)  评论(0)    收藏  举报