Создать функцию панели инструментов, не работающую с множественным выбором в сетке Telerik для MVC - PullRequest
0 голосов
/ 08 января 2019

Я получил мультиселект для работы внутри сетки для существующих элементов, но когда я выбираю «Добавить новую запись», я получаю ReferenceError: Роли не определены в javascript.

Я пытаюсь заполнить его списком IdentityRoles (сборка в EF).

Контроллер: открытый класс ManageAccountController: контроллер { private ApplicationDbContext db = new ApplicationDbContext ();

    public ActionResult Index()
    {
        List<RoleViewModel> roles = new List<RoleViewModel>();

        foreach(var _role in db.Roles)
        {
            roles.Add(new RoleViewModel { Id = _role.Id, Name = _role.Name });
        }


        ViewData["roles"] = roles;
        ViewData["defaultRoles"] = roles;
        return View();
    }

    public ActionResult ApplicationUsers_Read([DataSourceRequest]DataSourceRequest request)
    {

        var roleManager = new ApplicationRoleManager(new RoleStore<IdentityRole>(db));


        IQueryable<CustomUser> applicationusers;

        applicationusers = (from u in db.Users
                 select new CustomUser
                 {
                     Email = u.Email,
                     UserName = u.UserName,
                     PhoneNumber = u.PhoneNumber,
                     AccessFailedCount = u.AccessFailedCount,
                     LockoutEnabled = u.LockoutEnabled,
                     Password = "New",
                     Roles = (ICollection<IdentityRole>)db.Roles.Where(x => x.Users.Select(r => r.UserId).Contains(u.Id))
                 });



        DataSourceResult result = applicationusers.ToDataSourceResult(request, applicationUser => new {
            Email = applicationUser.Email,
            PhoneNumber = applicationUser.PhoneNumber,
            LockoutEnabled = applicationUser.LockoutEnabled,
            AccessFailedCount = applicationUser.AccessFailedCount,
            UserName = applicationUser.UserName,
            Password = applicationUser.Password,
            Roles = applicationUser.Roles
        });

        return Json(result);
    }

    //other non interesting stuff
}

Просмотр бритвы:

@(Html.Kendo().Grid<GrindrodDataCapture.Models.CustomUser>
                ()
                .Name("grid")
                .Columns(columns =>
                {
                    columns.Bound(c => c.Email).ClientTemplate("<div class=\"forTooltips\">#=Email#</div>").HtmlAttributes(new { @class = "overridePadding" });
                    columns.Bound(c => c.PhoneNumber);
                    columns.Bound(c => c.LockoutEnabled).Width(110).ClientTemplate("<input type='Checkbox'  disabled />");
                    columns.Bound(c => c.AccessFailedCount).Filterable(false).Sortable(false);
                    columns.Bound(c => c.UserName);
                    columns.Bound(c => c.Password).ClientTemplate("<input type='Password' style='width: 90px' disabled />").Filterable(false).Width(120);
                    columns.Bound(p => p.Roles).ClientTemplate("#=rolesTemplate(Roles)#").Width(200);/*.ClientTemplate("#=Roles.Name#").Width(120);*/
                    columns.Command(command => { command.Edit(); command.Destroy(); }).Width(200);
                })
                .ToolBar(toolbar =>
                {
                    toolbar.Create();
                })
                .Editable(editable => editable.Mode(GridEditMode.InLine))
                .Pageable()
                .Sortable(sortable =>
                {
                    sortable.SortMode(GridSortMode.SingleColumn);
                })
                .Filterable()
                .Scrollable()
                .DataSource(dataSource => dataSource
                .Ajax()
                .Model(model =>
                {
                    model.Id(p => p.UserName);
                    model.Field(p => p.AccessFailedCount).Editable(false);
                    model.Field(p => p.Roles).DefaultValue(ViewData["roles"] as Microsoft.AspNet.Identity.EntityFramework.IdentityRole);
                })
                .Read(read => read.Action("ApplicationUsers_Read", "ManageAccount"))
                .Create(create => create.Action("ApplicationUsers_Create", "ManageAccount"))
                .Update(update => update.Action("ApplicationUsers_Update", "ManageAccount"))
                .Destroy(destroy => destroy.Action("ApplicationUsers_Destroy", "ManageAccount"))
               )
)

@(Html.Kendo().Tooltip()
              .For("#grid")
              .Filter(".forTooltips")
              .ContentHandler("getEmailTooltip")
              .Position(TooltipPosition.Right)
              .AutoHide(true)
)
 <script type="text/kendo" id="rolesTemplate">
<ul>
    #if(data){#
    #for(var i = 0; i< data.length; i++){#
    <li>#:data[i].Name#</li>
    #}#
    #}#
</ul>
</script>
<script type="text/javascript">
var rolesTemplate = kendo.template($("#rolesTemplate").html(), { useWithBlock: false });
</script>
<script>
function getEmailTooltip(e) {
    var dataItem = $("#grid").data("kendoGrid").dataItem(e.target.closest("tr"));
    var content = dataItem.Email;
    return content;
}

</script>

Модель:

    public class CustomUser 
{
    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Required]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Phone]
    [Display(Name = "Phone Number")]
    public string PhoneNumber { get; set; }

    [Required]
    [Display(Name = "User Name")]
    public string UserName { get; set; }

    [Required]
    [Display(Name = "Failed Logins")]
    public int AccessFailedCount { get; set; }

    [Required]
    [Display(Name = "Locked?")]
    public bool LockoutEnabled { get; set; }


    [UIHint("ClientRoles")]
    [Display(Name = "Roles")]
    public ICollection<IdentityRole> Roles { get; set; }

}

public class RoleViewModel
{

    public string Id { get; set; }

    public string Name { get; set; }
}

У меня есть файл EditorTemplate, сохраненный в нужном месте, с именем ClientRoles:

@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
@(Html.Kendo().MultiSelect()
    .Name("Roles") //The name of the MultiSelect is mandatory. It specifies the "id" attribute of the widget.
    .DataTextField("Name") //Specify which property of the Roles to be used by the MultiSelect as a text.
    .DataValueField("Id") //Specify which property of the Roles to be used by the MultiSelect as a value.
    .BindTo((System.Collections.ICollection)ViewData["roles"]) //Pass the list of Roles to the MultiSelect.
)

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Я наконец понял это! При создании строки данные множественного выбора равны нулю, и Telerik не создает параметр при создании новой строки.

Мне пришлось изменить следующее:

columns.Bound(c => c.Roles).ClientTemplate("#=rolesTemplate(Roles)#").Width(200).Filterable(false);

Кому:

columns.Bound(c => c.Roles).ClientTemplate("#=(data.Roles) ? rolesTemplate(Roles) : ''#").Width(200).Filterable(false);
0 голосов
/ 08 января 2019

Не слишком уверен, но ваши роли, похоже, неправильно распределены по вашей реализации. ViewData["roles"] является List<RoleViewModel>.

В вашем редакторе поменяйте шаблон

.BindTo((System.Collections.ICollection)ViewData["roles"])

что-то вроде:

.BindTo((Models.RoleViewModel)ViewData["roles"])

Также

.Model(model => {
    model.Id(p => p.UserName);
    model.Field(p => p.AccessFailedCount).Editable(false);
    model.Field(p => p.Roles).DefaultValue(ViewData["roles"] as Microsoft.AspNet.Identity.EntityFramework.
}

может быть типа List<RoleViewModel>.

Я вижу, что ваша модель CustomUser имеет свойство public ICollection<IdentityRole> Roles { get; set; }, так что это может немного запутать.

...