【问题标题】:Automatically update viewModel after save to db保存到数据库后自动更新viewModel
【发布时间】:2014-08-09 18:11:48
【问题描述】:

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

这是我的服务器端代码:

    [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
    });
});

【问题讨论】:

  • 尝试使用可观察的绑定它会解决你的问题

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


【解决方案1】:
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;
});

【讨论】:

  • 谢谢..对了,你知道为什么我的self.oItemLeft在我推的时候没有增加吗?
  • 见我上面的编辑。如果您进行了更改,那么计算函数应该重新评估。
  • 遇到了一个新问题。刚刚编辑了我的一些cshtml代码。添加了一些复选框。你知道每当客户选中/取消选中复选框时我如何触发事件吗?
  • 您可以订阅复选框链接到的可观察对象:knockoutjs.com/documentation/observables.html 例如self.isChecked.subscribe(function(isChecked) { alert("复选框选中:" + newValue); });
猜你喜欢
  • 2017-10-05
  • 2017-02-13
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 1970-01-01
  • 2015-04-12
  • 1970-01-01
相关资源
最近更新 更多