【问题标题】:Knockout click handler not working for table created using ko.computed敲除点击处理程序不适用于使用 ko.computed 创建的表
【发布时间】:2015-05-05 08:07:50
【问题描述】:

我正在尝试将表格绑定到下拉菜单。以下是我的要求:

  • 下拉菜单包含菜单列表。

  • 一个菜单可以有许多关联的模块,这些模块显示在所选菜单项的表中。

  • 模块不必与 MENU 项相关联,在这种情况下,它被视为在所选菜单项之间共享。

这是我的屏幕示例:

在示例中,您可以看到 CommonShellModule 是共享的,这意味着将为所有菜单列出 CommonShellModule。

这是我目前所拥有的:

http://jsfiddle.net/fag62z1x/

视图模型:

var ModuleIndexViewModel = function (data) {
    var self = this;
    ko.mapping.fromJS(data, {}, self);

    self.selectedMenu = ko.observable();

    self.selectedMenuModules = ko.computed(function () {

        if (self.selectedMenu()) {

            //display modules for the selected menu or where they are not associated to a menu
            var modules = ko.utils.arrayFilter(self.Modules(), function (module) {
                return self.isModuleAssociatedToCurrentMenuSelection(module) || self.isSharedModule(module);
            });

            //return a sorted list of modules
            return modules.sort(function (left, right) {
                return left.Name() > right.Name() ? 1 : -1;
            }); 
        }
        return null;
    });

    self.isModuleAssociatedToCurrentMenuSelection = function (module) {
        if (self.selectedMenu()) {
            return module.MenuId() == self.selectedMenu().Id()
        }
        return false;
    }

    self.isSharedModule = function (module) {
        return module.MenuId() == null;
    }

    self.handleSharedCheckboxClick = function (module) {

        if (self.isSharedModule(module)) {
            module.MenuId(null);
        }
        else {
            module.MenuId(self.selectedMenu().Id());
        }

        return true; //allow the default click event action
    }
}

型号:

从中映射的模型(这些模型被序列化并传递到此视图模型):

public class IndexViewModel
{
    public IEnumerable<MenuViewModel> Menus { get; set; }
    public IEnumerable<ModuleViewModel> Modules { get; set; }
}

public class MenuViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ModuleViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? MenuId { get; set; }
}

查看:

...

<div class="form-group top-buffer">
    <label class="control-label" for="menu">Menu</label>
    <select id="menu" class="form-control" data-bind="options: Menus, optionsText: 'Name', value: selectedMenu"></select>
</div>

<div class="row top-buffer">
    <div class="col-lg-12">

        <table class="table table-striped">
            <thead>
                <tr>
                    <th class="col-lg-6">Module Name</th>
                    <th class="col-lg-3">Shared</th>
                    <th class="col-lg-3"></th>
                </tr>
            </thead>
            <tbody data-bind="foreach: selectedMenuModules">
                <tr>
                    <td data-bind="text: Name"></td>
                    <td><input type="checkbox" data-bind="checked: $parent.isSharedModule($data), click: $parent.handleSharedCheckboxClick" /></td>
                    <td><a href="#">Edit</a> | <a href="#">Details</a> | <a href="#">Delete</a></td>
                </tr>
            </tbody>
        </table>

    </div>
</div>

...

问题是 javascript handleSharedCheckboxClick 不起作用,我不知道为什么。每次单击共享复选框时都会执行它,但是当我更新此函数中的模块值时,不会重新计算计算出的剔除值,因此表会保留以前的值。

如果我能提供任何解决此问题的建议,我将不胜感激。

【问题讨论】:

  • 你能在 jsfiddle 中重现这个吗?
  • 我以前应该这样做的。我已经用http://jsfiddle.net/fag62z1x/ 的小提琴更新了这个问题。

标签: javascript knockout.js knockout-mapping-plugin


【解决方案1】:

编辑:我的错,用 findle 玩了一下,并且正在观察模块值,看起来问题出在这里:

self.handleSharedCheckboxClick = function (module) {

    if (self.isSharedModule(module)) {
        module.MenuId(null);
    }

如果模块是共享的,则该值已经为空,因此该值不会被更改,修改该代码添加 ! 如下:

self.handleSharedCheckboxClick = function (module) {

    if (!self.isSharedModule(module)) {
        module.MenuId(null);
    }

让它如你所愿工作,在菜单项值更新之间保存共享状态(单击选中的复选框,该行不再共享但绑定到当前菜单项,再次单击它并返回共享)

jsfindle:http://jsfiddle.net/yj1s9qod/

【讨论】:

  • 感谢您的回答。我会认为,如果我更新传递给点击处理程序的模块,那么淘汰计算将运行,因为模块是在计算中访问的 self.Modules() 的一部分?
  • 我仍然不确定我应该采取什么步骤来纠正这个问题,或者我是否需要以另一种方式重新设计这个视图模型。您对此有什么建议吗?
  • 检查我的更新是否有意义,看起来不需要重构:)
  • 我的错误。我没想到会这么简单。好地方。非常感谢您抽出宝贵时间查看此内容。
  • 没问题,我最近开始使用knockoutjs,我注意到它很快就会变得一团糟,尤其是使用映射插件...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 2017-08-17
  • 1970-01-01
  • 2012-06-17
相关资源
最近更新 更多