《ASP.NET MVC 4 实战》学习笔记 8:Ajax(下)

三、使用JSON和客户端模板的Ajax:

1.使用JSON的Ajax:
1)添加模型:

{
    public class Speaker
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string PictureUrl { get; set; }
        public string Bio { get; set; }

        public string FullName
        {
            get { return string.Format("{0} {1}", FirstName, LastName); }
        }
    }
}
View Code

2)添加模拟数据和方法:

namespace AjaxExamples.Models
{
    public class SpeakerRepository
    {
        //simulate an in memory database
        private static readonly List<Speaker> _speakers = new List<Speaker>();

        static SpeakerRepository()
        {
            _speakers = new List<Speaker> {

               new Speaker
                {
                    Id = 1,
                    FirstName = "Jimmy",
                    LastName = "Bogard",
                    PictureUrl = "/content/jimmy.png",
                    Bio = "Jimmy is a Principal Consultant at Headspring Systems in Austin, TX.",
                },
                new Speaker
                {
                    Id = 2,
                    FirstName = "Jeffrey",
                    LastName = "Palermo",
                    PictureUrl = "/content/jeffrey.jpg",
                    Bio = "Jeffrey Palermo is a Microsoft MVP and Chief Technology Officer of Headspring Systems in Austin, TX.",
                },
                new Speaker
                {
                    Id = 3,
                    FirstName = "Eric",
                    LastName = "Hexter",
                    PictureUrl = "/content/eric.jpg",
                    Bio = "Eric Hexter is an Enterprise Architect at Dell in Austin, TX.",
                },
                new Speaker
                {
                   Id = 4,
                   FirstName = "Matt",
                   LastName = "Hinze",
                   PictureUrl = "/content/matt.jpg",
                   Bio = "Matt Hinze is a Principal Consultant at Headspring Systems in Austin, TX.",
                },

               new Speaker
                {
                    Id = 5,
                    FirstName = "Jeremy",
                    LastName = "Skinner",
                    PictureUrl = "/content/jeremy.jpg",
                    Bio = "Jeremy Skinner is a C#/ASP.NET software developer in the UK.",
                }
            };


        }

        public IEnumerable<Speaker> FindAll()
        {
            return _speakers;
        }

        public Speaker FindSpeaker(int id)
        {
            return _speakers.SingleOrDefault(x => x.Id == id);
        }
    }
}
View Code

3)添加控制器:

namespace AjaxExamples.Controllers
{
    public class SpeakersController : Controller
    {
        private readonly SpeakerRepository _repository = new SpeakerRepository();
        public ActionResult Index()
        {
            var speakers = _repository.FindAll();
            return View(speakers);
        }
        public ActionResult Details(int id)
        {
            var speaker = _repository.FindSpeaker(id);
            return Json(speaker, JsonRequestBehavior.AllowGet);//将发言人序列成json
        }
    }
}

 4)添加视图:

@model IEnumerable<AjaxExamples.Models.Speaker>

<link href="@Url.Content("~/Content/speakers.css")" rel="stylesheet" />
<script src="@Url.Content("~/Scripts/jquery-1.10.2.min.js")"></script>
<script src="@Url.Content("~/Scripts/Speakers.js")"></script>

<ul class="speakers">
    @foreach (var speaker in Model)
    {
        <li>
            @Html.ActionLink(speaker.FullName, "Details", new { id = speaker.Id })
        </li>
    }
</ul>

<img id="indicator" src="~/Content/load.gif" alt="loading..." style="display:none;" />@*显示进度指示器*@

5)添加Speakers.js文件:

$(document).ready(function () {
    $("ul.speakers a").click(function (e) {
        e.preventDefault();
        $("#indicator").show();//显示进程指示器
        var url = $(this).attr(‘href‘);//接受URL
        $.getJSON(url, null, function (speaker) {//调用Ajax请求
            $("#indicator").hide();
            alert(speaker.FirstName);
        });
    });
}); 

上面的例子只是弹出发言人名字的模态对话框,下面我们将使用客户端模板显示更详细的信息。

2.客户端模板:
客户端模板能够在浏览器中动态地生成标记,而不必返回服务器。

1)下载jQuery-tmpl并引入项目:

2)修改视图:

@model IEnumerable<AjaxExamples.Models.Speaker>

<link href="@Url.Content("~/Content/speakers.css")" rel="stylesheet" />
<script src="@Url.Content("~/Scripts/jquery-1.10.2.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.tmpl.js")"></script>
<script src="@Url.Content("~/Scripts/Speakers.js")"></script>

<ul class="speakers">
    @foreach (var speaker in Model)
    {
        <li>
            @Html.ActionLink(speaker.FullName, "Details", new { id = speaker.Id })
        </li>
    }
</ul>

<img id="indicator" src="~/Content/load.gif" alt="loading..." style="display:none;" />@*显示进度指示器*@

<div class="selected-speaker" style="display:none">
</div>

<br style="clear:both" />

<script id="speakerTemplate" type="text/x-jquery-tmpl">@*定义模板*@
    <img src="${PictureUrl}" alt="Speaker image" class="speaker-pic" />@*照片模板*@
    <p class="speaker-bio">${Bio}</p>@*简历行模板*@

    <br style="clear:both;" />
</script>

3)修改Speakers.js:

$(document).ready(function () {
    $("ul.speakers a").click(function (e) {
        e.preventDefault();

        $(".selected-speaker").hide().html(‘‘);//隐藏发言人细节模板
        $("#indicator").show();

        var url = $(this).attr(‘href‘);

        $.getJSON(url, null, function (speaker) {
            $("#indicator").hide();

            $("#speakerTemplate")
                .tmpl(speaker)
                .appendTo(‘.selected-speaker‘);//渲染带有数据的模板

            $(‘.selected-speaker‘).show();
        });
    });
});

但是不幸的是会报错,没有找到原因,有没有人告诉我为什么。。。

3.最后润色:

如果浏览器禁用了javascript那么当点击发言人姓名时相应的JSON将作为文本文件下载而不会作为模板来渲染。

依然可以重写Details方法和添加Details视图解决:

public ActionResult Details(int id)
        {
            var speaker = _repository.FindSpeaker(id);
            if (Request.IsAjaxRequest())
            {
                return Json(speaker, JsonRequestBehavior.AllowGet);//将发言人序列成json
            }
            return View(speaker);

        }
@model AjaxExamples.Models.Speaker
@{
    ViewBag.Title = "Details";
}

<h2>发言人详细信息: @Model.FullName</h2>

<p class="speaker">
    <img src="@Model.PictureUrl" alt="@Model.FullName" />
<p class="speaker-bio">@Model.Bio</p>
</p>

<br style="clear:both" />
@Html.ActionLink("返回列表", "index")

但是也可以采用另一种方式--使用“动作方法选择器”来区分Ajax和非Ajax请求:

1)添加继承自ActionMethodSelectorAttribute的类:

namespace AjaxExamples
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class AcceptAjaxAttribute : ActionMethodSelectorAttribute
    {
        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
        {
            return controllerContext.HttpContext.Request.IsAjaxRequest();
        }
    }
}

如果当前动作是通过Ajax请求的AcceptAjaxAttribute便在IsValidForRequest方法中返回true。

2)将Details拆分成两个方法:

     [AcceptAjax]
        public ActionResult Details(int id)
        {
            var speaker = _repository.FindSpeaker(id);
            return Json(speaker, JsonRequestBehavior.AllowGet);
        }

        [ActionName("Details")]
        public ActionResult Details_NonAjax(int id)
        {
            var speaker = _repository.FindSpeaker(id);
            return View(speaker);
        }

上面方法第一个重载以AcceptAjaxAttribute注解用于处理Ajax请求,另一个用于常规请求。

四、创建自动完成文本框(jQuery UI):

 1)下载并引入jQuery UI

2)添加City模型:

namespace AjaxExamples.Models
{
    public class City
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string State { get; set; }

        public string DisplayName
        {
            get { return Name + ", " + State; }
        }
    }
}

3)添加模拟数据和方法:

namespace AjaxExamples.Controllers
{
    public class CityRepository
    {
        const string _csvFilename = "App_Data/cities.csv";
        static readonly List<City> _cities;

        static CityRepository()
        {
            string path = Path.Combine(HttpRuntime.AppDomainAppPath, _csvFilename);

            _cities = new List<City>();

            int id = 1;
            foreach (var line in File.ReadAllLines(path))
            {
                var lineSegments = line.Split(,);
                var name = lineSegments[0];
                var state = lineSegments[1];

                var city = new City { Id = id++, Name = name, State = state };
                _cities.Add(city);
            }
        }

        public City[] FindCities(string filter)
        {
            var cities = from city in _cities
                         where city.DisplayName.StartsWith(filter, StringComparison.CurrentCultureIgnoreCase)
                         select city;

            return cities.ToArray();
        }
    }
}
View Code

4)添加控制器:

namespace AjaxExamples.Controllers
{
    public class CitiesController : Controller
    {
        private readonly CityRepository _repository;

        public CitiesController()
        {
            _repository = new CityRepository();
        }

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Find(string term)
        {
            City[] cities = _repository.FindCities(term);

            var projection = from city in cities
                             select new
                             {
                                 id = city.Id,
                                 label = city.DisplayName,
                                 value = city.DisplayName
                             };

            return Json(projection.ToList(), JsonRequestBehavior.AllowGet);
        }
    }
}

5)添加视图:

<link href="@Url.Content("~/Content/jquery-ui.css")" rel="stylesheet" />

<p>
    <label for="city">城市</label>
    <input type="text" id="city" />
</p>

<script src="@Url.Content("~/Scripts/jquery-1.10.2.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery-ui.js")"></script>

<script type="text/javascript">
    $(function () {
        var autocompleteUrl = @Url.Action("Find");
        $("input#city").autocomplete({
            source: autocompleteUrl,
            minLength: 2,
            select: function (event, ui) {
                alert("选中 " + ui.item.label);
            }
        });
    });
</script>

但是不幸的是还是会报错,原因应该和上面一样,有没有人告诉我为什么。。。

源码下载 密码:53my

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。