【问题标题】:Conditional data-binds in KnockoutJsKnockoutJs 中的条件数据绑定
【发布时间】:2014-04-24 00:47:45
【问题描述】:

我在 <tbody> 上有一个自定义绑定处理程序,我只想在用户拥有来自 Viewmodel 的适当权限时应用它。此数据绑定允许用户拖放表格中的元素以重新排序列表。

如果满足某些条件,是否可以有条件地对我的自定义绑定处理程序进行数据绑定?

基本上我想要:

<tbody data-bind="if (hasPermission){custom-binding: list}"></tbody>

这种行为可以通过淘汰赛来实现吗?我认为我可以采用其他策略,例如有一个允许用户对表格进行排序的按钮(仅在他具有正确权限时才显示),但我想检查是否有其他方法。

谢谢。

编辑

我对自己提出的解决方案感觉不太好,但它让我得到了想要的结果:

        <!--ko if: hasPermission-->
        <tbody data-bind="foreach: list, sortableList: list">
            @Html.Partial("_FilesTabTableBody")
        </tbody>
        <!-- /ko -->
        <!--ko if: !hasPermission()-->
        <tbody data-bind="foreach: list">
            @Html.Partial("_FilesTabTableBody")
        </tbody>
        <!-- /ko -->

基本上我只是在两个地方复制 HTML。它并不漂亮,但确实可以。感谢大家的意见。

【问题讨论】:

  • 我只是想知道,在您进行编辑后,如果用户有权限,您是否知道服务器端?因为那样你就可以渲染适当的 html 服务器端。
  • 这是一个很好的直觉。当用户与列表交互时,hasPermission 实际上会发生变化,所以我不能使用模板化的 HTML 来完成这一切。好主意!

标签: javascript knockout.js


【解决方案1】:

自定义绑定的好处是您可以完全控制。在您的自定义绑定中,您可以添加另一个参数来控制绑定的行为方式。例如,您可以创建一个可见绑定,该绑定仅在另一个 observable 为 true 时才生效:

var vm = function() {
    var me = this;

    me.canChangeVisible = ko.observable(true);
    me.showMessage = ko.observable(true);
}

ko.applyBindings(new vm());

HTML:

<div>
    <div><input type="checkbox" data-bind="checked: canChangeVisible">Can Change Visible</input></div>
    <div><input type="checkbox" data-bind="checked: showMessage">Show Message</input></div>
</div>
<div data-bind="makeVisible: showMessage, basedOn: canChangeVisible">Message</div>

在您的自定义绑定中,查看“basedOn”以查看是否应该使用它:

ko.bindingHandlers.makeVisible = {
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var bo = allBindings.get('basedOn');
        var canChange = bo == null ? true : ko.unwrap(bo);
        if( canChange )
            ko.bindingHandlers.visible.update(element, valueAccessor, allBindings, viewModel, bindingContext);
    }
};

这是一个完整的jsFiddle 展示了这一点。 “显示消息”复选框的设置仅在选中“可以更改可见”时使用。

【讨论】:

  • 这真是太聪明了。非常感谢!
【解决方案2】:

您可以使用虚拟元素。

<!-- ko if: hasPermission -->
<tbody data-bind="custom-binding: list"></tbody>
<!-- /ko -->

【讨论】:

  • 感谢您的回复。无论如何,我都想保留 节点,只是不希望它在某些情况下具有自定义绑定。 tbody 也有一个 data-bind: foreach 来枚举列表中的所有行。
  • 如果您的视图模型不包含任何项目,如果用户无权查看它们,那将是最干净的。因此,无论如何在视图中执行此操作都是错误的。计算可能有效,但实际上您的 API 甚至根本不应该返回这些项目。混淆用户不应该看到的内容不是一个好策略。
  • 抱歉,我想我们可能缺少通讯。我想让用户看到这个列表中的元素,我只是不希望他们能够重新排序,除非他们有权限。就是这样。
  • 啊,好的。在这种情况下,我可能会使用自定义绑定 sortable: hasPermission
  • 对于没有权限的用户,您有什么替代方案,您仍然使用相同的list吗?您能否将@Tomalak 的答案与&lt;!-- ifnot: hasPermission --&gt;&lt;tbody data-bind="foreach: list"&gt;...&lt;/tbody&gt;&lt;!-- /ko --&gt; 结合起来?
【解决方案3】:

使用计算...?

<tbody data-bind="custom-binding: safeList"></tbody>

vm.safeList = ko.computed(function() {
    if (vm.hasPermission) return vm.list;
    return undefined; // or whatever you do when user has no permission
});

【讨论】:

  • 感谢您帮助我入门。自定义绑定使用 jquery UI 使表中的行可拖放。我仍然在该节点上有一个 foreach 绑定来枚举所有行。如果我的自定义绑定处理程序应用于未定义的 ,我相信它仍然允许用户拖放行。
  • 在这种情况下,您可以为您的 foreach 绑定进行另一个计算,当用户没有权限时,它将返回一个空数组(或其他)。
猜你喜欢
相关资源
最近更新 更多
热门标签