如何使用knockout.js实现取消功能

时间:2014-02-19 20:57:24

标签: html knockout.js

我正在开发一个asp.net MVC项目。我在我的浏览页面上使用knockout.js。 我正在尝试开发数据输入网格。一切正常,除了取消按钮。

如果我在我的UI(视图)上更改某些内容并单击取消,则不显示旧值。仅显示最新值。

步骤:

  • 当我点击编辑按钮时,它会显示更新和取消按钮。
  • 我们说我已经编辑过数据并点击取消,它不应该反映在我的用户界面上。

现在,即使您编辑并点击取消按钮,也可以恢复旧状态。

当我点击取消按钮时,我不会回到旧状态。 请给我一些例子。

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Type Lookup....</title>
    <script src="~/Scripts/jquery-2.1.0.js"></script>
    <script src="~/Scripts/knockout-3.0.0.js"></script>

    <link href="~/Content/Site.css" rel="stylesheet" />
    <link href="~/Content/bootstrap.css" rel="stylesheet" />
    <script type="text/javascript">
        viewModel = {
            lookupCollection: ko.observableArray()
        };

        //wrapper to an observable that requires accept/cancel
        ko.protectedObservable = function (initialValue) {
            //private variables
            var _actualValue = ko.observable(initialValue),
                _tempValue = initialValue;

            //computed observable that we will return
            var result = ko.computed({
                //always return the actual value
                read: function () {
                    return _actualValue();
                },
                //stored in a temporary spot until commit
                write: function (newValue) {
                    _tempValue = newValue;
                }
            });

            //if different, commit temp value
            result.commit = function () {
                if (_tempValue !== _actualValue()) {
                    _actualValue(_tempValue);
                }
            };

            //force subscribers to take original
            result.reset = function () {
                _actualValue.valueHasMutated();
                _tempValue = _actualValue();   //reset temp value
            };

            return result;
        };

        $(document).ready(function () {
            $.ajax({
                type: "GET",
                url: "/Home/GetIndex",
            }).done(function (data) {
                $(data).each(function (index, element) {
                    var mappedItem =
                        {
                            Id: ko.observable(element.Id),
                            Key: ko.observable(element.Key),
                            Value: ko.observable(element.Value),
                            Mode: ko.observable("display")
                        };
                    viewModel.lookupCollection.push(mappedItem);
                });
                ko.applyBindings(viewModel);
            }).error(function (ex) {
                alert("Error.....");
            });


            $(document).on("click", ".kout-edit", null, function (ev) {
                var current = ko.dataFor(this);
                current.Mode("edit");
            });

            $(document).on("click", ".kout-update", null, function (ev) {
                var current = ko.dataFor(this);
                saveData(current);
                current.Mode("display");
            });

            $(document).on("click", ".kout-cancel", null, function (ev) {
               var current = ko.dataFor(this);
               current.Mode("display");
            });

            $(document).on("click", "#create", null, function (ev) {
                var current = {
                    Id: ko.observable(0),
                    Key: ko.observable(),
                    Value: ko.observable(),
                    Mode: ko.observable("edit")
                }
                viewModel.lookupCollection.push(current);
            });

            function saveData(currentData) {
                var postUrl = "";
                var submitData = {
                    Id: currentData.Id(),
                    Key: currentData.Key(),
                    Value: currentData.Value()

                };

                if (currentData.Id && currentData.Id() > 0) {
                    postUrl = "/Home/Edit"
                }
                else {
                    postUrl = "/Home/Create"
                }
                $.ajax({
                    type: "POST",
                    contentType: "application/json",
                    url: postUrl,
                    data: JSON.stringify(submitData)
                }).done(function (id) {
                    currentData.Id(id);
                }).error(function (ex) {
                    alert("ERROR Saving....");
                })
            }

        });

    </script>
</head>
<body>
    <div>
        <p>
            <button class="btn btn-primary" id="create">Create</button>
        </p>
        <table class="table">
            <tr>
                <th>Key
                </th>
                <th>Value
                </th>
                <th>Action
                </th>
            </tr>

            <tbody data-bind="foreach: lookupCollection">
                <tr data-bind="template: { name: Mode, data: $data }">
                </tr>
            </tbody>
        </table>

        <script type="text/html" id="display">
            <td data-bind="text: Key"></td>
            <td data-bind="text: Value"></td>
            <td>
                <button class="btn btn-success kout-edit">Edit</button>
                <button class="btn btn-danger kout-delete">Delete</button>
            </td>
        </script>

        <script type="text/html" id="edit">
            <td>
                <input type="text" data-bind="value: Key" /></td>
            <td>
                <input type="text" data-bind="value: Value" /></td>
            <td>
                <button class="btn btn-success kout-update">Update</button>
                <button class="btn btn-danger kout-cancel">Cancel</button>
            </td>
        </script>
    </div>
</body>
</html>

3 个答案:

答案 0 :(得分:1)

我稍微修改了你的代码。

var mappedItem =
{
 Id: ko.observable(element.Id),
 Key: ko.observable(element.Key),
 Value: ko.observable(element.Value),
 Mode: ko.observable("display"),
 oldData: ko.observable()
};

我添加了oldData observable,以便在单击编辑按钮时保留以前的数据。所以当你点击取消数据时,将通过“olData”observable恢复。 见下面的代码。

$(document).on("click", ".kout-edit", null, function (ev) {
    var current = ko.dataFor(this);
    current.oldData(ko.toJS(current));
    current.Mode("edit");
});

$(document).on("click", ".kout-update", null, function (ev) {
    var current = ko.dataFor(this);
    current.oldData(null);
    saveData(current);
    current.Mode("display");
});

$(document).on("click", ".kout-cancel", null, function (ev) {
    var current = ko.dataFor(this);
    current.Id(current.oldData().Id);
    current.Value(current.oldData().Value);
    current.Key(current.oldData().Key);
    current.Mode("display");
    current.oldData(null);
});

以下是Jsfiddle

的工作示例

答案 1 :(得分:1)

使用此

 ko.observable.fn.revertable = function () {

    var self = this, originalValue = self();

    if (!originalValue) {
        self.subscribe(function () {
            originalValue = originalValue || self();
        });
    }

    self.commit = function () {
        originalValue = self();
    };

    self.revert = function () {
        self(originalValue || '');
    };

    self.isDirty = function () {
        return (self() != originalValue);
    };

    return self;
};

和你的观察者一样

this.text=ko.observable().revertable();

我假设你有取消功能,所以你可以像

那样做
this.text.revert();

如果您想保存这些更改,那么

this.text.commit();

答案 2 :(得分:0)

您的代码中有protectedObservable,但您没有使用它。将您的“模型”(您想要“取消”的数据)转换为protectedObservable。取消时,调用data.reset()。保存时,请调用data.commit()。

小例子(不完整):

        $(document).on("click", ".kout-cancel", null, function (ev) {
           var current = ko.dataFor(this);
           current.reset();
           current.Mode("display");
        });

        $(document).on("click", "#create", null, function (ev) {
            var current = ko.protectedObservable({
                Id: ko.observable(0),
                Key: ko.observable(),
                Value: ko.observable(),
                Mode: ko.observable("edit")
            });
            viewModel.lookupCollection.push(current);
        });
相关问题