保存到db后自动更新viewModel

时间:2014-06-19 08:57:58

标签: asp.net-mvc knockout.js knockout-mapping-plugin

我想要实现的是一旦数据被保存到数据库中,当它返回到客户端时,它将自动更新可观察数组。但不知怎的,我无法实现它。

这是我的服务器端代码:

    [HttpGet]
    public JsonResult GetTasks()
    {
        var tasks = context.ToDoTasks.ToList();

        return Json(tasks.Select(c => new TaskViewModel(c)).ToList(), JsonRequestBehavior.AllowGet);
    }

    [HttpPost]
    public JsonResult AddTask(string text, string date)
    {
        var nTask = new ToDoTask()
        {
            Text = text,
            Date = DateTime.ParseExact(date, "MM/dd/yyyy", System.Globalization.CultureInfo.InvariantCulture),
            IsDone = false,
            Order = 1,
        };

        context.ToDoTasks.Add(nTask);
        context.SaveChanges();

        return Json(new TaskViewModel(nTask), JsonRequestBehavior.AllowGet); 
    }

这是我的cshtml文件代码:

        <form>
            <div class="controls controls-row" style="margin-top:40px;">
                <input class="span7" type="text" placeholder="Task to do" style="margin-right:4px;" id="oText">
                <div id="task-date" class="input-append date">
                    <input data-format="MM/dd/yyyy" type="text" placeholder="MM/dd/yyyy" name="taskDate" id="oDate" />
                    <span class="add-on">
                        <i data-time-icon="icon-time" data-date-icon="icon-calendar">
                        </i>
                    </span>
                </div>
                <button class="btn" type="submit" style="margin-top:-10px;" data-bind="click: save">+</button>
            </div>
            <div class="controls">
                <label class="checkbox">
                    <input type="checkbox"> Mark all as complete
                </label>
            </div>
            <div id="task-section" style="margin-top:20px;">
                <ul data-bind="foreach: Tasks">
                    <!-- ko if: IsDone -->
                    <li>
                        <span><input type="checkbox" style="margin:-5px 5px 0px 0px;" data-bind="checked: IsDone" /></span>
                        <del><span data-bind="text: Text"></span></del>
                        <del><span class="task-date" data-bind="text: Date"></span></del>
                    </li>
                    <!-- /ko -->
                    <!-- ko ifnot: IsDone -->
                    <li>
                        <span><input type="checkbox" style="margin:-5px 5px 0px 0px;" data-bind="checked: IsDone" /></span>
                        <span data-bind="text: Text"></span>
                        <span class="task-date" data-bind="text: Date"></span>
                    </li>
                    <!-- /ko -->
                </ul>
            </div>
            <div class="clearfix" style="margin-top:30px;">
                <span class="pull-left" style="font-weight:bold;"><span data-bind="text: oItemLeft"></span> item left</span>
                <span class="pull-right badge" style="cursor:pointer;" data-bind="click: remove">Clear # completed item</span>
            </div>
        </form>

最后我的JS:

var ViewModel = function (data) {
    var self = this;
    self.Tasks = ko.mapping.fromJS(data, {}, self.Tasks);
    self.oItemLeft = ko.computed(function () {
        var i = 0;
        data.forEach(function (entry) {
            if (!entry.IsDone) i++;
        });

        return i;
    });

    self.save = function () {
        $.ajax({
            url: "Home/AddTask",
            type: "POST",
            data: { text: $('#oText').val(), date: $('#oDate').val() },
            success: function (response) {
                ko.mapping.fromJS(response, ViewModel);
            }
        });
    };
    self.remove = function () {
        alert('delete');
    }
}

$(function () {
    $.getJSON("/Home/GetTasks/", null, function (data) {
        ko.applyBindings(new ViewModel(data));
    });

    // for datepicker
    $('#task-date').datetimepicker({
        language: 'pt-BR',
        pickTime: false
    });
});

1 个答案:

答案 0 :(得分:2)

self.save = function () {
    $.ajax({
        url: "Home/AddTask",
        type: "POST",
        data: { text: $('#oText').val(), date: $('#oDate').val() },
        success: function (response) {
            var task = ko.mapping.fromJS(response);
            self.Tasks.push(task);
        }
    });
};

同样对于oItemLeft,你应该指的是self.Tasks而不是数据:

self.oItemLeft = ko.computed(function () {
    var i = 0;
    self.Tasks().forEach(function (entry) {
        if (!entry.IsDone) i++;
    });

    return i;
});