Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc ASP.NET MVC 4嵌套视图模型Ajax_Asp.net Mvc_Mvvm_Asp.net Mvc 4 - Fatal编程技术网

Asp.net mvc ASP.NET MVC 4嵌套视图模型Ajax

Asp.net mvc ASP.NET MVC 4嵌套视图模型Ajax,asp.net-mvc,mvvm,asp.net-mvc-4,Asp.net Mvc,Mvvm,Asp.net Mvc 4,也许我的想法是错误的,因为我最近对WPF和MVVM进行了深入研究,但是我的Web项目中有以下ViewModels public class Route { public Address Source {get; set;} public Address Destination {get; set;} } public class Address { public string Text {get; set;} public Location Location {

也许我的想法是错误的,因为我最近对WPF和MVVM进行了深入研究,但是我的Web项目中有以下ViewModels

public class Route
{
    public Address Source {get; set;}
    public Address Destination {get; set;}
}

public class Address
{
    public string Text {get; set;}
    public Location Location {get; set;}
}

puclic class Location
{
    [Required]
    public double? Latitude {get; set;}
    [Required]
    public double? Longitude {get; set;}
}

public class Search
{
    public Route {get; set;}
    public IEnumerable<Route> Results {get; set;}
}
如果不清楚我想做什么-我想让用户在源框和目标框中输入一些搜索文本,然后得到结果。当用户选择一个自动完成选项时,源和目标框应该通过Ajax自动完成,并填充Address.Location.Latitude和Address.Location.Longitude

最后,一旦用户拥有有效的源和目标位置,Home.cshtml上的Submit按钮应该通过Ajax调用,以获取搜索结果并将其绑定到网格

我想是相当标准的东西

我正在努力用“最干净”的方式来实现以下目标:

  • 由于位置实际上不显示在地址视图中的任何位置(仅显示文本),如何让ASP.NET MVC的DataAnnotations验证启动并帮助我验证

  • 当用户选择一个自动完成选项时,我如何获取位置值,使其返回Home.cshtml,Home.cshtml应该通过Ajax调用发布路由对象

  • 如何在源和目标中维护用户所选地址的“状态”?是否将选择处理程序添加到自动完成?但是,对所选的值做什么呢

  • 我希望这是清楚的…但如果没有,请告诉我,我会尽力澄清。

    您可以使用。让我们举个例子

    我们可以有以下型号:

    public class Route
    {
        public Address Source { get; set; }
        public Address Destination { get; set; }
    }
    
    public class Address
    {
        [Required]
        [ValidCity("Location", ErrorMessage = "Please select a valid city")]
        public string Text { get; set; }
        public Location Location { get; set; }
    }
    
    public class Location
    {
        public double? Latitude { get; set; }
        public double? Longitude { get; set; }
    }
    
    public class Search
    {
        public Route RouteSearch { get; set; }
        public IEnumerable<Route> Results { get; set; }
    }
    
    然后控制器:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = new Search
            {
                RouteSearch = new Route
                {
                    Source = new Address(),
                    Destination = new Address()
                }
            };
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(Route search)
        {
            if (!ModelState.IsValid)
            {
                return PartialView("_Route", search);
            }
    
            // TODO: do the search here and return the results:
    
            var lat1 = Math.PI * search.Source.Location.Latitude.Value / 180;
            var lon1 = Math.PI * search.Source.Location.Longitude.Value / 180;
    
            var lat2 = Math.PI * search.Destination.Location.Latitude.Value / 180;
            var lon2 = Math.PI * search.Destination.Location.Longitude.Value / 180;
    
            var R = 6371;
            var distance = Math.Acos(Math.Sin(lat1) * Math.Sin(lat2) +
                              Math.Cos(lat1) * Math.Cos(lat2) *
                              Math.Cos(lon2 - lon1)) * R;
            return Json(new { distance = distance });
        }
    
        public ActionResult GetLocation(string text)
        {
            var results = new[]
            {
                new { city = "Paris", latitude = 48.8567, longitude = 2.3508 },
                new { city = "London", latitude = 51.507222, longitude = -0.1275 },
                new { city = "Madrid", latitude = 40.4, longitude = -3.683333 },
                new { city = "Berlin", latitude = 52.500556, longitude = 13.398889 },
            }.Where(x => x.city.IndexOf(text, StringComparison.OrdinalIgnoreCase) > -1);
    
            return Json(results, JsonRequestBehavior.AllowGet);
        }
    }
    
    相应的
    ~/Views/Home/Index.cshtml
    视图:

    @model Search
    
    @using (Ajax.BeginForm(new AjaxOptions { OnSuccess = "searchComplete" }))
    {
        <div id="search">
            @Html.Partial("_Route", Model.RouteSearch)
        </div>
        <p><button type="submit">OK</button></p>
    }
    
    地址类的编辑器模板(
    ~/Views/Home/EditorTemplates/Address.cshtml
    ):


    啊…我缺少的东西是:HiddenFor,用来捕获信息,以及BeginForm在顶层捕获child部分视图上的HiddenFor。非常感谢!关于验证文本的部分,而不是位置Lat/Long…很棒的东西。
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = new Search
            {
                RouteSearch = new Route
                {
                    Source = new Address(),
                    Destination = new Address()
                }
            };
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(Route search)
        {
            if (!ModelState.IsValid)
            {
                return PartialView("_Route", search);
            }
    
            // TODO: do the search here and return the results:
    
            var lat1 = Math.PI * search.Source.Location.Latitude.Value / 180;
            var lon1 = Math.PI * search.Source.Location.Longitude.Value / 180;
    
            var lat2 = Math.PI * search.Destination.Location.Latitude.Value / 180;
            var lon2 = Math.PI * search.Destination.Location.Longitude.Value / 180;
    
            var R = 6371;
            var distance = Math.Acos(Math.Sin(lat1) * Math.Sin(lat2) +
                              Math.Cos(lat1) * Math.Cos(lat2) *
                              Math.Cos(lon2 - lon1)) * R;
            return Json(new { distance = distance });
        }
    
        public ActionResult GetLocation(string text)
        {
            var results = new[]
            {
                new { city = "Paris", latitude = 48.8567, longitude = 2.3508 },
                new { city = "London", latitude = 51.507222, longitude = -0.1275 },
                new { city = "Madrid", latitude = 40.4, longitude = -3.683333 },
                new { city = "Berlin", latitude = 52.500556, longitude = 13.398889 },
            }.Where(x => x.city.IndexOf(text, StringComparison.OrdinalIgnoreCase) > -1);
    
            return Json(results, JsonRequestBehavior.AllowGet);
        }
    }
    
    @model Search
    
    @using (Ajax.BeginForm(new AjaxOptions { OnSuccess = "searchComplete" }))
    {
        <div id="search">
            @Html.Partial("_Route", Model.RouteSearch)
        </div>
        <p><button type="submit">OK</button></p>
    }
    
    @model ToDD.Controllers.Route
    
    <h3>Source</h3>
    @Html.EditorFor(x => x.Source)
    
    <h3>Destination</h3>
    @Html.EditorFor(x => x.Destination)
    
    @model Address
    
    <span class="address">
        @Html.TextBoxFor(x => x.Text, new { data_url = Url.Action("GetLocation") })
        @Html.ValidationMessageFor(x => x.Text)
        @Html.HiddenFor(x => x.Location.Latitude, new { @class = "lat" })
        @Html.HiddenFor(x => x.Location.Longitude, new { @class = "lon" })
    </span>
    
    <script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery-ui-1.8.20.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
    
    var searchComplete = function (result) {
        if (result.distance) {
            alert('the distance is ' + result.distance);
        } else {
            $('#search').html(result);
            attachAutoComplete();
        }
    };
    
    var attachAutoComplete = function () {
        $('.address :text').autocomplete({
            source: function (request, response) {
                $.ajax({
                    url: $(this.element).data('url'),
                    type: 'GET',
                    cache: false,
                    data: { text: request.term },
                    context: response,
                    success: function (result) {
                        this($.map(result, function (item) {
                            return {
                                label: item.city,
                                value: item.city,
                                latitude: item.latitude,
                                longitude: item.longitude
                            };
                        }));
                    }
                });
            },
            select: function (event, ui) {
                var address = $(this).closest('.address');
                address.find('.lat').val(ui.item.latitude);
                address.find('.lon').val(ui.item.longitude);
            },
            minLength: 2
        }).change(function () {
            var address = $(this).closest('.address');
            address.find('.lat').val('');
            address.find('.lon').val('');
        });
    }
    
    $(document).ready(attachAutoComplete);