【问题标题】:Trying to do color animation for TR by custom binding尝试通过自定义绑定为 TR 做彩色动画
【发布时间】:2015-06-08 19:11:01
【问题描述】:

我正在尝试通过自定义绑定为 TR 制作彩色动画,但没有按预期工作。我犯了一些错误,因为我是 KnockoutJS 的新手。所以请告诉我我需要在我的代码中修复哪个区域。

错误在这里AnimateRow : $parent.Hasfade() 我有一个名为 Hasfade 的属性,我用 false 进行初始化,但是当插入或更新行时,我设置为 true。

自定义绑定代码

    ko.bindingHandlers.AnimateRow = {
        update: function (element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor());
            alert(value);
            $(element).animate({ backgroundColor: "#FCFCD8" }, 300).delay(1000).animate({ backgroundColor: "#EFEAEA" }, 500);

        }
    }

该值正在变为 null,但它假设为 true,因为我在可观察数组中插入和更新数据时进行了设置。请指导我进行修复。

这是我的完整代码。

<head id="Head1" runat="server">
    <title></title>
    <style type="text/css">
        table.imagetable
        {
            font-family: verdana, arial, sans-serif;
            font-size: 11px;
            color: #333333;
            border-width: 1px;
            border-color: #999999;
            border-collapse: collapse;
        }
        table.imagetable th
        {
            background: #b5cfd2;
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #999999;
        }
        table.imagetable td
        {
            background: #dcddc0;
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #999999;
        }
        tr.mutating td
        {
            background-color: #efe;
        }
    </style>
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script src="Scripts/knockout-3.3.0.js" type="text/javascript"></script>
    <script src="Scripts/knockout.mapping.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(document).ready(function () {
            ko.bindingHandlers.AnimateRow = {
                update: function (element, valueAccessor) {
                    var value = ko.utils.unwrapObservable(valueAccessor());
                    alert(value);
                    $(element).animate({ backgroundColor: "#FCFCD8" }, 300).delay(1000).animate({ backgroundColor: "#EFEAEA" }, 500);

                }
            }

            var StockItem = function (_id, _name, _price, _status) {
                var self = this;
                self.id = ko.observable(_id);
                self.name = ko.observable(_name);
                self.price = ko.observable(_price);
                self.status = ko.observable(_status);
                self.mutating = ko.observable(false);
            };

            var data = [
            new StockItem("12345", "Acme Widget 1", "£25.99", "In Stock"),
            new StockItem("67890", "Acme Widget 2", "£28.99", "In Stock"),
            new StockItem("11123", "Acme Widget 3", "£15.99", "In Stock"),
            new StockItem("14156", "Acme Widget 4", "£33.99", "In Stock")];

            var NewData = [new StockItem("99999", "HSL Limited", "£78.99", "In Stock")];

            var appViewModel = function () {
                var self = this;
                self.Hasfade = ko.observableArray(false);
                self.Stocks = ko.observableArray(data);

                self.AddNewData = function () {
                    self.Stocks.push.apply(self.Stocks, NewData);
                    NewData.forEach(markMutated);
                };

                self.DeleteItem = function (dataContext) {
                    var itemToDelete = dataContext;
                    self.Stocks.remove(itemToDelete);
                }

                self.UpdateDataByIds = function () {
                    var id1 = '11123';
                    var id2 = '12345';
                    self.UpdateById(id1, null, null, "Out of Stock");
                    self.UpdateById(id2, null, "31.45", null);
                };

                function markMutated(item) {
                    item.Hasfade(true);
                    setTimeout(function () {
                        item.Hasfade(false);
                    }, 800);
                }

                self.UpdateById = function (_id, _name, _price, _status) {
                    var matchedItem = ko.utils.arrayFirst(self.Stocks(), function (item) {
                        return item.id() === _id;
                    });

                    if (matchedItem != null) {
                        if (_name != null) matchedItem.name(_name);
                        if (_price != null) matchedItem.price(_price);
                        if (_status != null) matchedItem.status(_status);
                        markMutated(matchedItem);
                    }
                };

                self.UpdateData = function (dataContext) {
                    var itemToEdit = dataContext;
                    itemToEdit.status("Out of Stock");
                    markMutated(itemToEdit);
                };
            };

            var vm = new appViewModel();
            ko.applyBindings(vm);
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <button data-bind="click: AddNewData">Add New Data</button>

    <button data-bind="click: UpdateDataByIds">Update Data</button>

    <br>
    <br>
    <table class="imagetable">
        <thead>
            <tr>
                <th>
                    ID
                </th>
                <th>
                    Name
                </th>
                <th>
                    Price
                </th>
                <th>
                    Status
                </th>
                <th>
                    Edit
                </th>
                <th>
                    Delete
                </th>
            </tr>
        </thead>
        <tbody data-bind="foreach: Stocks">
            <tr data-bind="attr: { id: 'tr_' + $index() } , AnimateRow : $parent.Hasfade()">
                <td data-bind="text: id">
                </td>
                <td data-bind="text: name">
                </td>
                <td data-bind="text: price">
                </td>
                <td data-bind="text: status">
                </td>
                <td>
                    <a href="#" data-bind="click: $parent.UpdateData">edit</a>
                </td>
                <td>
                    <a href="#" data-bind="click: $parent.DeleteItem">delete</a>
                </td>
            </tr>
        </tbody>
    </table>
    </form>
</body>

谢谢

【问题讨论】:

  • 请参阅"Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”!
  • 当HasFade 在当前正在迭代的项目中时,为什么要使用$parent 关键字?试试AnimateRow : Hasfade。此外,如果您不介意旧浏览器,最好使用 CSS3 动画,摆脱自定义的 AnimateRow 处理程序,改用 css 处理程序。
  • @haim770 根据您的建议,我更改了代码。这是 jsfiddle 链接jsfiddle.net/tridip/o47suzqo/6 现在它正在工作,但自定义绑定更新部分在将数据插入 Observable 数组时触发了两次......你能告诉我为什么会这样吗?为什么将数据插入 Observable 数组时自定义绑定更新部分会触发两次?

标签: jquery knockout.js


【解决方案1】:
  1. 您将Hasfade 设为observableArray 而不是observable。
  2. item 没有 Hasfade。它是 appModel 的一个属性。
  3. 除了打开 Hasfade 之外,您不会做任何事情。
  4. 绑定处理程序只会在行更新时触发;更新其各个部分不会导致处理程序触发

处理程序在行创建时触发,但没有动画可见。 Animations are not supported on table rows.

【讨论】:

  • 是的,我修复了它,但是当我从函数 markMutated 设置值 true 时,自定义绑定显示 false 作为值,因为我在那里发出警报。
  • 为什么这条线不起作用$(element).animate({ backgroundColor: "#FCFCD8" }, 300).delay(1000).animate({ backgroundColor: "#EFEAEA" }, 500);
  • 您是否在运行 Chrome 调试器的情况下测试您的应用?还是 Firefox 中的 Firebug?你应该得到错误。我正在 Fiddle 中运行您的代码:jsfiddle.net/o47suzqo,Chrome 调试器会在遇到错误时告诉我。
  • 嗨,请参阅这些 jsfiddle 链接 jsfiddle.net/62Ls6x9n/173 jsfiddle.net/62Ls6x9n/163 在这里你可以看到 css 绑定是如何工作的......在这里他们声明了不属于的 mutated 属性项目,但它在单击行编辑按钮时起作用。所以不是我的工作。你能纠正我的代码吗?谢谢
  • 我更新了jsfiddle链接jsfiddle.net/tridip/o47suzqo/12还是淡入效果不是很流畅。所以寻找建议以平滑淡入淡出效果。谢谢
猜你喜欢
  • 1970-01-01
  • 2022-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多