更新强类型视图的最佳方法(MVC 3.0)

时间:2011-03-15 18:30:33

标签: jquery asp.net-mvc-3

我有一个强类型的类别视图,显示所有类别(在网格中)... 在该网格下我有字段添加/编辑新的类别详细信息:几个文本框和radiobox,如: - 分类名称 - 类别说明 - 分类图像 等

因此,当用户选择Grid上的Category时,它会通过JQuery Ajax填充字段......

  $.ajax({
        url: '/Category/Get',
        type: 'POST',
        dataType: 'json',
        data: {
            idCategory: ...
        }
    })
    .success(function(category,success) {                
        // Update TextBox fields
        $(".ajax").each(function(){
            $(this).val(category[$(this).attr("id")]);
        });
        //Other fields ...             
     })      

我的控制器

[HttpPost]
public ActionResult Get(string idCategory)
{
     if (ModelState.IsValid)
     {
         var _category = _categoryRepository.Get(Convert.ToInt16(idCategory));

         if (Request.IsAjaxRequest())
             return Json(_category);
         return RedirectToAction("Index");
     }
     if (Request.IsAjaxRequest())
         return Json(new Category());
     return View();
 }

工作正常!

但是我想知道这是否是最好的方式......有可能以另一种方式做到吗?也许使用Ajax.BeginForm?

由于

1 个答案:

答案 0 :(得分:2)

在我看来,有两种方法可以做到这一点。

1)每次更改网格中的选定类别时,都会返回包含类别字段的局部视图。不要打扰JSON。

2)如果你想使用JSON(我可能会这样做),那么使用像Knockout.JS这样的框架来处理绑定。它看起来像这样:

<div id="current">
    Name: <input type="text" data-bind="value: Name"/><br/>
    Description: <input type="text" data-bind="value: Description"/><br/>
    <input type="button" value="Save" data-bind="click: Save" />
</div>

// javascript viewmodel w/ observable properties (except Id)
var Category = function(original) {
this.Id = original.Id;
this.Name = ko.observable(original.Name);
this.Description = ko.observable(original.Description);

this.asJson = function() {
    return {
        Id: this.Id,
        Name: this.Name(), // call observables as method to get underlying value
        Description: this.Description()
    };
};

this.Save = function() {
    $.post("/Category/Update", $.toJSON(this.asJson()));
};
}

$.post('/Category/Get', { idCategory: ... }, function(response) {
    var viewModel = new Category(response);
    ko.applyBindings(viewModel, $("#current"));
}, "json");

您的行动可能会简化为

[HttpPost]
public ActionResult Get(int idCategory)
{
    var category = _categoryRepository.Get(idCategory) ?? new Category();
    return Json(category)
}

然后保存只是做你通常在服务器上做的事情

[HttpPost]
public ActionResult Update(Category updated)
{
    var category = _categoryRepository.Get(updated.Id);
    // todo: update category with values from updated model
}

修改

如果您不想多次调用applyBindings,则可以使用模板。 (我没有测试这段代码,但它应该非常接近。)

<div id="current" data-bind="template: {name: 'categoryTemplate', data: Current}"/>
<input type="button" value="Save" data-bind="click: Save" />

<script type="text/html" id="categoryTemplate">
    Name: <input type="text" data-bind="value: Name"/><br/>
    Description: <input type="text" data-bind="value: Description"/>
</script>

// javascript viewmodel w/ observable properties (except Id)
var Category = function(original) {
    this.Id = original.Id;
    this.Name = ko.observable(original.Name);
    this.Description = ko.observable(original.Description);

    this.asJson = function() {
        return {
            Id: this.Id,
            Name: this.Name(), // call observables as method to get underlying value
            Description: this.Description()
        };
    };
}

var viewModel = 
{
    Current = ko.observable({}),
    Save = function() {
        $.ajax({
                url: "/Category/Update", 
                data: $.toJSON(this.Current().asJson()),
                type: "POST",
                contentType: "application/json; charset=utf-8"
            });
    }
};

$.post('/Category/Get', { idCategory: ... }, function(response) {
    viewModel.Current(new Category(response));
}, "json");

$(function(){
    ko.applyBindings(viewModel, $("#current"));
});