将ViewModel传递回控制器

时间:2014-03-10 23:07:31

标签: asp.net-mvc-4 twitter-bootstrap-3 viewmodel knockout-3.0

我有一个集成Bootstrap和Knockout的工作应用程序。这个应用程序从我的控制器中提取数据,并在UI中显示,如我所料。当我单击或更改值时,我可以看到值已更新,但我似乎无法看到数据传回我的控制器以保存它。我需要知道的是如何修复我必须允许我将selectedRequestorName传递回控制器。

这是一个示例类

public class Requestor
{
    public int Id { get; set; }
    public string Name { get; set; }
}

接口

interface IRequestorRepository
{
    IList<Requestor> GetAllRequestors();
}

这是包含种子数据的存储库

public class RequestorRepository : IRequestorRepository
{
    private List<Requestor> requestors = new List<Requestor>();
    private int _nextId = 1;

    public RequestorRepository()
    {
        Add(new Requestor{ Id = 1, Name = "Brian" });
        Add(new Requestor { Id = 2, Name = "Steve" });
        Add(new Requestor { Id = 3, Name = "Jake" });
    }

    public IList<Requestor> GetAllRequestors()
    {
        return requestors;
    }

    public Requestor Add(Requestor item)
    {
        if (item == null)
        {
            throw new ArgumentNullException("Null Requestor");
        }

        item.Id = _nextId++;
        requestors.Add(item);

        return item;
    }
}

我的HomeController看起来如下

public class HomeController : Controller
{
    static readonly IRequestorRepository req_repository = new RequestorRepository();

    // GET: /Home/
    public ActionResult Index()
    {
        ViewBag.DateNow = DateTime.Now.ToShortDateString();

        return View();
    }

    public JsonResult GetRequestors()
    {
        return Json(req_repository.GetAllRequestors(), JsonRequestBehavior.AllowGet);
    }

    [HttpPost]
    public JsonResult SaveDetails(Requestor selectedRequestorName)
    {
        int id = -1;

        return Json(id, "json");
    }
}

在我的Index.cshtml中,我在页面顶部的脚本标记中有以下内容

// Global variable
var viewModel = null;

$(document).ready(function () {
    function ViewModel() {

        //Make the self as 'this' reference
        var self = this;

        // Requestors
        self.RequestorId = ko.observable("");
        self.RequestorName = ko.observable("");
        self.RequestorSourceDatabase = ko.observable("");

        var RequestorNames = {
            Id: self.RequestorId,
            Name: self.RequestorName,
            SourceDatabase: self.RequestorSourceDatabase
        };

        self.selectedRequestorName = ko.observable();
        self.RequestorNames = ko.observableArray();   // Contains the list of RequestorNames

        // Initialize the view-model for Requestors
        $.ajax({
            url: '@Url.Action("GetRequestors", "Home")',
            cache: false,
            type: 'GET',
            contentType: 'application/json; charset=utf-8',
            data: {},
            success: function (data) {
                self.RequestorNames(data);
            }
        });
        // END Requestors

        // Reset
        self.reset = function () {
            self.Name("");
        }

        // Cancel
        self.cancel = function () {
            self.Name(null);
        }
    }

    viewModel = new ViewModel();
    ko.applyBindings(viewModel);        
});

$(function () {
        $('#Save').click(function (e) {

            // Check whether the form is valid. Note: Remove this check, if you are not using HTML5
            if (document.forms[0].checkValidity()) {

                e.preventDefault();

                $.ajax({
                    type: "POST",
                    url: '@Url.Action("SaveDetails", "Home")',
                    data: ko.toJSON(viewModel.selectedRequestorName),
                    contentType: 'application/json; charset=utf-8',
                    async: true,
                    beforeSend: function () {
                        // Display loading image
                    },
                    success: function (result) {
                        if (result > 0) {
                            alert("This work request has been successfully saved in database. The Document ID is: " + result);
                        } else {
                            alert("The Work Request was not saved, there was an issue.");
                        }
                    },
                    complete: function () {
                        // Hide loading image.
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        // Handle error.
                    }
                });

            }
            else {
                alert("Form is not valid");
            }
        });
});

最后是包含显示数据的控件,供用户选择......

<p>Current selection is <span data-bind="text:selectedRequestorName"></span></p>
<!-- Requestors -->
<div class="input-group col-sm-8">
  <input type="text" data-bind="value:selectedRequestorName" class="form-control item" placeholder="Requestor Name" name="Requestor">
    <div class="input-group-btn">
      <button type="button" class="btn btn-default dropdown-toggle item" data-toggle="dropdown">Select <span class="caret"></span></button>
        <ul class="dropdown-menu" data-bind="foreach: RequestorNames">
          <li class="dropdown">
            <a href="#" data-bind="text: Name, value: Id, click: function() { $root.selectedRequestorName(Name); }"></a>
          </li>
        </ul>
     </div>
  </div>
  <div>
    <button id="Save" type="submit" class="btn btn-default btn-success">Create</button>
  </div>

3 个答案:

答案 0 :(得分:0)

  • 在控制器上创建一个动作方法,接受selectedRequestorName(string?)作为参数。
  • 在你的knockout viewmodel中创建一个函数,它从ko vm中读取selectedRequestorName,JsonStringify它并通过ajax将它传递给上面的action方法。

答案 1 :(得分:0)

[HttpPost]
    public JsonResult SaveDetails(String selectedRequestorName)
    {
        int id = -1;

        return Json(id, "json");
    }

将requestRequestorName的类型从Requestor更改为String,如上所述。

注意未经测试。但请告诉我是否有帮助。

答案 2 :(得分:0)

$('#Save').click()内,请您更改

数据:ko.toJSON(viewModel.selectedRequestorName)

数据:ko.toJSON(viewModel.selectedRequestorName())

希望,这会有所帮助。