如何将模型通过MVC控制器传递给引导模式

时间:2015-08-09 19:35:08

标签: asp.net-mvc angularjs entity-framework twitter-bootstrap asp.net-mvc-4

我一直在研究这个问题,我认为我很接近。我正在尝试使用bootstrap模式编辑MVC applicationUsers。我使用Angular进行绑定,当我点击User时,id被传递给Angular控制器,然后传递给MVC控制器。我以为我可以发布到控制器中的编辑操作并返回模型的模态。我无法完成这项工作。我为模态创建了一个Action,它打开就好了。但没有附加模型。我怎么能让这个工作?

  $scope.editUser = function (id) {
            var modalInstance = $modal.open({
                templateUrl: 'UsersAdmin/EditUserModal',
                controller: $scope.modalEdit,
                //matches of the id of your item to recover object model in the controller of the modal
                resolve: {
                    id: function () {
                        return id
                    }
                }
            });
        };

        //controller of the modal. Inside you can recover your object with ajax request
        $scope.modalEdit = function ($scope, $modalInstance, id) {
            if (angular.isDefined(id)) {
                var reqGetCustomer = $http({ url: '/UsersAdmin/Edit/' + id, method: 'GET' });
                reqGetCustomer.success(function (dataResult) {
                    $scope.model = dataResult;
                });
            } else { alert('id is undefined'); }
            //function to close modal
            $scope.cancel = function () {
                $modalInstance.dismiss('cancel');
            }
        }

使用用户列表查看

<tbody>
  @foreach (var item in Model)
    {
      <tr>
        <td>
     @Html.DisplayFor(modelItem => item.FullName)
       </td>
      <td class="text-left" style="width:225px">
       @Html.ActionLink("Edit", "Edit", null, new { ng_click = "editUser('" + @item.Id + "')" })
        </td>
          </tr>
     }
 </tbody>

MVC控制器

 public ActionResult EditUserModal(string id)
    { 
        return View();
    }

    // GET: /Users/Edit/1
    public async Task<ActionResult> Edit(string id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        ViewBag.RoleId = new SelectList(RoleManager.Roles, "Id", "Name");

        var user = await UserManager.FindByIdAsync(id); 
        if (user == null)
        {
            return HttpNotFound();
        }
        var userRoles = await UserManager.GetRolesAsync(user.Id);

        var companies = await _userCompanyService.GetCompaniesAsync();
        var selectedCompanies = companies.Where(c => c.Users.Any(u => u.Id == user.Id)).Select(c => c.Id).ToArray();
        var model = new EditUserViewModel()
        {
            Id = user.Id,
            UserName = user.UserName,
            FullName = user.FullName,
            RolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem()
            {
                Selected = userRoles.Contains(x.Name),
                Text = x.Name,
                Value = x.Name
            }),
            CompanyList = new MultiSelectList(companies.Select(c => new 
            {
                Name = c.Name,
                Id = c.Id
            }), 
            "Id", "Name", selectedCompanies),
            SelectedCompanies = selectedCompanies
        };



        return View(model);
    }

BootstrAP MODAL

@model TransparentEnergy.Models.EditUserViewModel
@{
    Layout = null;
 }
<div class="modal-header">
    <h3 class="modal-title">Edit User</h3>
</div>
<div class="modal-body">
    <div class="row">
        <div class="col-md-12">
            @using (Html.BeginForm())
            {
                @Html.AntiForgeryToken()
                @Html.ValidationSummary(true)
                @Html.HiddenFor(model => model.Id)
                <div class="card-body card-padding">
                    <div class="form-group">
                        <label for="UserName" class="col-md-2 control-label">UserName</label>
                        <div class="col-md-10">
                            <div class="fg-line">
                                @Html.TextBoxFor(m => m.UserName, new { @class = "form-control fg-input" })
                                @Html.ValidationMessageFor(model => model.UserName)
                            </div>
                        </div>
                    </div>

                    <div class="col-sm-9">
                        <div class="form-group fg-line">
                            <label for="SelectedRoles" class="control-label">Roles</label>
                            @foreach (var item in Model.RolesList)
                            {
                                <input type="checkbox" name="SelectedRoles" value="@item.Value" checked="@item.Selected" class="checkbox-inline" />
                                @Html.Label(item.Value, new { @class = "control-label" })
                            }
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-2">
                            <button type="submit" class="btn bgm-blue waves-effect btn-width">Save</button>
                        </div>
                    </div>
                </div>
            }
        </div>
    </div>
</div>
<div class="row">
    <div class="col-md-12">
        <div class="modal-footer">
            <button class="btn bgm-orange waves-effect btn-width" ng-click="cancel()">Close</button>
        </div>
    </div>
</div>

2 个答案:

答案 0 :(得分:2)

最佳做法是:

1)在控制器中写入方法(或者如果您将WebApi写入传递数据到客户端,则更好)

2)编写适用于您的API的Angular SERVICE。

3)为您编写控制器和指令页面。

一切都会很容易。当您需要数据时 - 您只需从指令调用角度服务即可。 Anf in view(bootstrap model)使用指令属性。

这是一个小例子:

 public class DoorsController : ApiContollerBase
    {

      [HttpGet]
      public IEnumerable<DoorViewModel> AdminGetDictionaries()
      {
         //here i just return List of my doors
        return Doors.GetDoors();
      }

}

客户方:

服务:

angular
        .module('adminApp.services.adminData', ['ngResource'])
        .factory('AdminData', ['$resource', 'AppConfig', function ($resource, AppConfig) {
            return function (dataName, customActionNames) {
                customActionNames = customActionNames || {};

                var actions = {
                    getItem: { method: 'GET', url: AppConfig.apiUrl + 'api/' + dataName + '/' + (customActionNames['getItem'] || 'Test') + '/:id' },
                    getItems: { method: 'GET', isArray: true, url: AppConfig.apiUrl + dataName + '/' + (customActionNames['getItems'] || 'AdminGet') + '/' },
                    getItemsForTable: { method: 'POST', url: AppConfig.apiUrl + 'api/' + dataName + '/' + (customActionNames['getItemsForTable'] || 'AdminGetForTable') + '/' },
                    getDictionaries: { method: 'GET', isArray: true, url: AppConfig.apiUrl + 'api/' + dataName + '/' + (customActionNames['getDictionaries'] || 'AdminGetDictionaries') + '/' },
                    postItem: { method: 'POST', url: AppConfig.apiUrl + 'api/' + dataName + '/' + (customActionNames['postItem'] || 'AdminPost') + '/' },
                    putItem: { method: 'PUT', url: AppConfig.apiUrl + 'api/' + dataName + '/' + (customActionNames['putItem'] || 'AdminPut') + '/:id' },
                    deleteItem: { method: 'DELETE', url: AppConfig.apiUrl + dataName + '/' + (customActionNames['deleteItem'] || 'AdminDelete') + '/:id' },
                };

                var resource = $resource(AppConfig.apiUrl + dataName + '/:id', null, actions);

                return {
                    getItem: function (id) {
                        return resource.getItem({ id: id });
                    },

                    getItems: function () {
                        return resource.getItems();
                    },

                    getItemsForTable: function (params) {
                        return resource.getItemsForTable(params);
                    },
                    getDictionaries: function (params) {
                        return resource.getDictionaries(params);
                    },

                    createItem: function (item) {
                        return resource.postItem({}, item);
                    },

                    updateItem: function (id, item) {
                        return resource.putItem({ id: id }, item);
                    },

                    deleteItem: function (id) {
                        return resource.deleteItem({ id: id });
                    }
                }
            }
        }]);

指令:

(function () {
    'use strict';

    angular
        .module('adminApp.directives.adminTableArea', ['adminApp.directives', 'adminApp.services'])
        .directive('adminTableArea', function () {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: '/App/Admin/views/General/admin-table-area.html',
                scope: {
                    options: "="
                },

                controller: ['$scope', '$translate', 'AdminData', 'DictionaryProvider', '$state', '$window',
                    function ($scope, $translate, AdminData, DictionaryProvider, $state, $window) {
                        var vm = this;

                        var data = AdminData(vm.dataSource, vm.dataActionNames);
....etc...

我希望它会帮助你。

祝你好运。 问候, 大卫

答案 1 :(得分:1)

最后以最简单的方式弄明白了。没有自定义的MVC助手或不必要的jquery。

以下是包含表格的索引视图

 <div class="table-responsive">
                            <table class="table table-vmiddle">
                                <thead>
                                    <tr>
                                        <th>Full Name</th>
                                        <th>Email</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    @foreach (var item in Model)
                                    {
                                        <tr>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.FullName)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.Email)
                                            </td>
                                            <td class="text-left" style="width:100px">
                                                @Html.ActionLink("Edit", "Edit", new { id = item.Id }, new { @class = "btn bgm-gray waves-effect edit" })
                                            </td>
                                            <td class="text-left" style="width:100px">
                                                @Html.ActionLink("Delete", "Edit", null, new { ng_click = "deleteUser('" + @item.Id + "')", @class = "btn" })
                                            </td>
                                        </tr>
                                    }
                                </tbody>
                            </table>
                        </div>

这里是角度控制器

  $('a.edit').on('click', function () {
            $.ajax({
                url: this.href,
                type: 'GET',
                cache: false,
                success: function (result) {
                    $('#myModal').html(result).find('.modal').modal({
                        show: true,
                        backdrop: false
                    });
                }
            });
            return false;
        });

        $scope.deleteUser = function (id) {
            ApplicationUserDelete.remove(id).success(function (result) {
            }).error(function (err, result) {
                console.log(err, result);
            });
        };

返回PartialView的MVC控制器操作

 // GET: /Users/Edit/1
    public async Task<ActionResult> Edit(string id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        ViewBag.RoleId = new SelectList(RoleManager.Roles, "Id", "Name");

        var user = await UserManager.FindByIdAsync(id);
        if (user == null)
        {
            return HttpNotFound();
        }
        var userRoles = await UserManager.GetRolesAsync(user.Id);

        var companies = await _userCompanyService.GetCompaniesAsync();
        var selectedCompanies = companies.Where(c => c.Users.Any(u => u.Id == user.Id)).Select(c => c.Id).ToArray();
        var model = new EditUserViewModel()
        {
            Id = user.Id,
            UserName = user.UserName,
            FullName = user.FullName,
            RolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem()
            {
                Selected = userRoles.Contains(x.Name),
                Text = x.Name,
                Value = x.Name
            }),
            CompanyList = new MultiSelectList(companies.Select(c => new
            {
                Name = c.Name,
                Id = c.Id
            }),
            "Id", "Name", selectedCompanies),
            SelectedCompanies = selectedCompanies
        };
        return PartialView(model);
    }

部分模态视图

@model TransparentEnergy.Models.EditUserViewModel
@{
   Layout = null;
   }
    <div class="modal fade" tabindex="-1" role="dialog" aria- labelledby="myModalLabel" data-ng-controller="ApplicationUserController">
       <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                  <h4 class="modal-title">Edit User</h4>
            </div>
            <div class="modal-body margin-top30px">
                <div class="row">
                    <div class="col-md-12">
                        @using (Html.BeginForm())
                    {
                            @Html.AntiForgeryToken()
                            @Html.ValidationSummary(true)
                            @Html.HiddenFor(model => model.Id)
                            <div class="z-depth-1 padding20 background-white">
                            <div class="card-body card-padding">
                                <div class="form-group margin-bottom10px">
                                    <label for="FullName" class="col-md-2 control-label">Full Name</label>
                                    <div class="col-md-10">
                                        <div class="fg-line">
                                            @Html.TextBoxFor(m => m.FullName, new { @class = "form-control fg-input" })
                                            @Html.ValidationMessageFor(model => model.FullName)
                                        </div>
                                    </div>
                                    <td>&nbsp;</td>
                                </div>
                                <div class="form-group margin-bottom10px">
                                    <label for="UserName" class="col-md-2 control-label">Email</label>
                                    <div class="col-md-10">
                                        <div class="fg-line">
                                            @Html.TextBoxFor(m => m.UserName, new { @class = "form-control fg-input" })
                                            @Html.ValidationMessageFor(model => model.UserName)
                                        </div>
                                    </div>
                                    <td>&nbsp;</td>
                                </div>
                                <div class="form-group margin-bottom10px">

                                    <label for="SelectedRoles" class="col-md-2 control-label">Roles</label>
                                    <div class="col-md-10">
                                        @foreach (var item in Model.RolesList)
                                    {
                                            <label class="checkbox checkbox-inline m-r-20">
                                                <input type="checkbox" name="SelectedRoles" value="@item.Value" checked="@item.Selected" />
                                                <i class="input-helper"></i>
                                                @Html.Label(item.Value, new { @class = "control-label" })
                                            </label>
                                    }
                                    </div>
                                    <td>&nbsp;</td>
                                </div>
                                <div class="form-group margin-bottom10px">
                                    <label for="SelectedCompanies" class="col-md-2 control-label">Companies</label>
                                    <div class="col-md-10">
                                        <div class="fg-line">
                                            @Html.ListBoxFor(model => model.SelectedCompanies, Model.CompanyList, new { @class = "form-control" })
                                        </div>
                                    </div>
                                    <td>&nbsp;</td>
                                </div>
                                <div class="form-group" style="margin-bottom:60px">
                                    <div class="col-md-2">
                                        <button type="submit" class="btn bgm-blue waves-effect btn-width">Save</button>
                                    </div>
                                </div>
                            </div>
                            </div>
                    }
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <div class="modal-footer">
                        <button class="btn bgm-orange waves-effect btn-width" data-dismiss="modal">Close</button>
                    </div>
                </div>
            </div>
            @section Scripts {
                @Scripts.Render("~/bundles/jqueryval")
            }
        </div>
    </div>
</div>

View模型在任何方面都没有受到影响。希望这有助于某人。不能相信没有简化的方法来做到这一点!