2

나는 Ajax 바인딩 된 Razor가있는 MVC 3 애플리케이션에서 Telerik MVC 그리드를 사용하고 있습니다. 이제는 사용자가 편집 모드에서 사용할 수 있도록 드롭 목록 열을 추가하려고 시도하지만이를 파악할 수는 없습니다. 그리드에는 제품 목록이 표시되며 드롭 목록에 Product를 연결할 수있는 ProductCategories 컬렉션이 포함되도록하고 싶습니다. 나는 지금 몇 시간 동안이 일을 해왔고 아이디어가 없습니다. 나는 여기 누군가가 도울 수 있기를 정말로 바란다 :Telerik MVC Grid : 열에 DropDownList를 사용하는 방법?

나는 telerik 데모를 참조하고 있는데, 이것은 here이다.

나를 매달고있는 부분은 데모가 사용하는 도움말보기에 있다고 생각합니다. 이 데모에서는 "ClientEmployee (Editor)"라고합니다. 제 경우에는 "ProductCategoryDropList.cshtml"이라는 파일에 도우미를 배치했습니다. 이 도우미에서 DropDownList를 올바르게 바인딩하는 데 어려움을 겪고 있습니다. 어떻게 든 올바른 데이터로 BindTo() 메서드를 설정하지 않기 때문에이 문제가 발생할 수 있다고 생각합니다. "new SelectList()"생성자 호출의 첫 번째 매개 변수로 "SomeCollectionReference"와 함께 아래의 예제 DropDownList Helper 코드에서이 혼란을 지적했습니다. 그 자리에 "Model"을 넣으려고하면 NullReferecne 예외가 발생합니다. 목록이 포함 된 ViewBag 데이터에 액세스하려고하면 "SelectList에 ProductCategoryID 열이 없습니다"와 비슷한 메시지가 표시됩니다. 그래서, 나는 무엇을 시도해야할지 모르겠습니다.

내 문제에 대한 설명이 얼마나 명확한지는 잘 모르겠지만, 완성을위한 노력의 일환으로 아래에 관련 있다고 생각되는 코드를 포함 시켰습니다.

컨트롤러 :

public ActionResult Index() 
{ 
    ViewBag.ProductCategories = new SelectList(_productCategoryService.GetActiveProductCategories(), "ProductCategoryID", "ProductcategoryName"); 
    var products = _productService.GetProducts().ToList(); 
    var presentationModel = _mapper.MapAsList(products); 
    return View(presentationModel); 
} 

// 
// GET: /Product/ 
[GridAction] 
public ViewResult _Index() 
{ 
    ViewBag.ProductCategories = new SelectList(_productCategoryService.GetActiveProductCategories(), "ProductCategoryID", "ProductcategoryName"); 
    return View(new GridModel<ProductPresentationModel> 
        { 
         Data = _mapper.MapAsList(_productService.GetProducts().ToList()) 
        }); 
} 

보기 : 나는 배치하여 그것을 단순화하기 위해 노력했습니다

이 조금 긴하지만, 다음에 "// < --- DropList 여기에" 내가 함께 일하려고하는 칼럼에.

@model IEnumerable<Models.PresentationModels.ProductPresentationModel> 

@(Html.Telerik().Grid(Model).HtmlAttributes(new { style = "width: 100%;" }) 
     // Give the Grid an HTML id attribute value 
     .Name("ProductGrid") 
     // Establish the promiry key, to be used for Insert, Update, and Delete commands 
     .DataKeys(dataKeys => dataKeys.Add(p => p.ProductID)) 
     // Add an Insert command to the Grid Toolbar 
     .ToolBar(commands => commands.Insert().ButtonType(GridButtonType.ImageAndText)) 
     // Using Ajax Data Binding to bind data to the grid 
     .DataBinding(dataBinding => dataBinding 
       // Ajax Binding 
       .Ajax() 
        .Select("_Index", "Product") 
        // Home.Insert inserts a new data record 
        .Insert("Create", "Product") 
        // Home.Update updates an existing data record 
        .Update("Edit", "Product") 
        // Home.Delete deletes an existing data record 
        .Delete("Delete", "Product") 
     ) 
     .Columns(columns => 
     { 
      columns.Bound(p => p.ProductName).Width(120); 
      columns.Bound(p => p.ProductDescription).Width(150); 
      columns.Bound(p => p.PricePerMonth).Width(120); 
      columns.Bound(p => p.ProductImagePath).Width(150) 
      columns.Bound(p => p.ProductActive).Width(120) 
       .ClientTemplate("<input type='checkbox' disabled='disabled' name='Active' <#= ProductActive ? checked='checked' : '' #> />"); 
      columns.Bound(p => p.ProductCategoryName); // <--- DropList Here 
      columns.Command(commands => 
      { 
       commands.Edit().ButtonType(GridButtonType.Image); 
       commands.Delete().ButtonType(GridButtonType.Image); 
      }); 
     }) 
     .Editable(editing => editing.Mode(GridEditMode.PopUp)) 
     .ClientEvents(events => events.OnEdit("onEdit")) 
     .Pageable() 
     .Scrollable() 
     .Sortable() 
     .Filterable() 
) 

@section HeadContent { 
    <script type="text/javascript"> 
     function onEdit(e) { 
      $(e.form).find('#ProductCategoryName').data('tDropDownList').select(function (dataItem) { 
       return dataItem.Text == e.dataItem['ProductCategoryName']; 
      }); 
     } 
    </script> 
} 

모델 :

[DisplayName(@"Category Name")] 
[UIHint("ProductCategoryDropList"), Required] 
[StringLength(255, ErrorMessage = @"Product Category Name cannot be more than 255 characters in length")] 
public string ProductCategoryName 
{ 
    get 
    { 
     string name = string.Empty; 

     if (_model.ProductCategory != null) 
     { 
      name = _model.ProductCategory.ProductCategoryName; 
     } 

     return name; 
    } 
    set 
    { 
     if (_model.ProductCategory != null) 
     { 
      _model.ProductCategory.ProductCategoryName = value; 
     } 
    } 
} 

DropList 도우미 :

@model Models.PresentationModels.ProductPresentationModel 

@(Html.Telerik().DropDownList() 
     .Name("ProductCategoryName") 
      .BindTo(new SelectList(<SomeCollectionReference>, "ProductCategoryID", "ProductCategoryName")) 
) 

ProductMapper :

public List<ProductPresentationModel> MapAsList(List<Product> products) 
{ 
    //var categoryList = new SelectList(_productCategoryService.GetProductCategories().ToList(), "ProductCategoryID", "ProductCategoryName"); 

    var presentationModels = products 
      .Select(x => new ProductPresentationModel() 
      { 
       ProductID = x.ProductID, 
       ProductCategoryID = ((x.ProductCategory != null) ? x.ProductCategory.ProductCategoryID : 0), 
       ProductCategoryName = ((x.ProductCategory != null) ? x.ProductCategory.ProductCategoryName : String.Empty), 
       ProductName = x.ProductName, 
       ProductDescription = x.ProductDescription, 
       PricePerMonth = x.PricePerMonth, 
       ProductImagePath = x.ProductImagePath, 
       ProductActive = x.ProductActive, 
       ProductCategories = new SelectList(_productCategoryService.GetProductCategories().ToList(), "ProductCategoryID", "ProductCategoryName")//categoryList 
      }).ToList(); 

    return presentationModels; 
} 

답변

0

저는 Telerik의 좋은 사람들에게이 문제에 대해 물어 보았습니다. 드롭 다운리스트 부분보기는 아약스 편집 을 렌더링하기 때문에

모델이 null : 여기에 그들이 내게 준 대답은. 이 경우 그리드는 모든 부분 뷰 편집기 템플릿을 미리 렌더링하여 클라이언트 측에서 사용할 수 있도록합니다. 이 경우 모델은 null이됩니다. 서버 바인딩을 사용하고 모델 을 편집하면 올바른 값으로 설정됩니다.

이 시점에서 나는이 질문을 내 질문의 대답으로 받아 들일 것입니다. 이 경우 내 자신의 대답을 받아 들여야한다는 것은 유감 스럽지만 ... 글쎄, 나는 선택할 다른 사람을 얻지 못했다. :)

1

나는 이것을 다소 다룰 수 있었지만, 나는 아직도 질문을 가지고있다. 여기에 내가이 작업을 얻을 변경 내용은 다음과 같습니다 그리고 ...과 같이

public ActionResult Index() 
{ 
    // ViewData object here ... 
    ViewData["ProductCategories"] = new SelectList(_productCategoryService.GetActiveProductCategories(), "ProductCategoryID", "ProductCategoryName"); 
    var products = _productService.GetProducts().ToList(); 
    var presentationModel = _mapper.MapAsList(products); 
    return View(presentationModel); 
} 

// 
// GET: /Product/ 
[GridAction] 
public ViewResult _Index() 
{ 
    // ViewData object here ... 
    ViewData["ProductCategories"] = new SelectList(_productCategoryService.GetActiveProductCategories(), "ProductCategoryID", "ProductCategoryName"); 
    return View(new GridModel<ProductPresentationModel> 
        { 
         Data = _mapper.MapAsList(_productService.GetProducts().ToList()) 
        }); 
} 

컨트롤러에을 ViewData 개체를 생성, 나는 ...

이처럼 DropDownListHelper에서을 ViewData 개체를 사용
@using System.Collections 
@model Models.PresentationModels.ProductPresentationModel 

@(Html.Telerik().DropDownList() 
     .Name("ProductCategoryName") 
     .BindTo(new SelectList((IEnumerable)ViewData["ProductCategories"], "Value", "Text")) 
); 

내 질문은 지금 ... ViewData 개체를 사용해야합니까? 내 모델의 자산을 사용할 수 있기를 바랍니다. 그러나 어떤 이유로 든 내 모델은 Helper 파일에서 항상 NULL입니다. 그리드 생성 코드 안에 DropDownList 코드를 삽입하려고하면 DropDownList가 전혀 작동하지 않습니다.

다른 옵션이 있습니까?

1

현재 나는 글을 쓸 때 동일한 문제에 직면 해있다. Telerik 친구들이 당신에게 쓴 것을 진실로. 부분 뷰는 서버 (컨텐츠 포함)에 사전 렌더링됩니다. 허용되는 값의 목록이 정적이지만 충분한 해결책이 될 수 있지만 ...

... 각 그리드 행에 대해 허용되는 값의 목록이 다르고 싶다고 상상해보십시오. 그 경우이 개념은 실현 가능하지 않습니다 ...

그리드 내에 하나의 콤보가 있기 때문에 (내가 찾은 해결책 중 하나는) AJAX를 사용하여 허용 된 값으로 콤보 상자를 databind 할 수있는 onEdit 그리드 이벤트를 처리하는 것입니다 . 그리드 onEdit 핸들러에서 적절한 행의 모든 ​​데이터 필드에 액세스 할 수 있으므로 바인딩 용도로 사용할 수 있습니다.

안부, Ondrej.

+0

훌륭한 정보, Ondrej. 이 게시물을 예제 또는 두 가지로 업데이트하여 설명 한 내용을 설명 할 수 있습니까? – campbelt

관련 문제