我有如下简化的代码。我想做的是用从下面的UL LI列表中单击的值更新输入框,然后隐藏该列表。

<input data-bind="value: Name, hasfocus: isSelected" />
<ul data-bind="foreach: NameList, visible: isSelected">
    <li data-bind="text: $data, click: function () { $root.Name($data); }"></li>
</ul>

查看模型
  function VM()
    {
        var self = this;
        self.isSelected = ko.observable(false);
        self.Name = ko.observable();
        self.NameList = ko.observableArray();
        self.NameList.push("A");
        self.NameList.push("B");
        self.NameList.push("C");
        self.NameList.push("D");
        self.NameList.push("E");
        self.NameList.push("F");
    }

    ko.applyBindings(new VM());

除非我尝试在对焦时隐藏UL,否则它将起作用。 (删除可见:UL中的isSelected 以查看其工作原理)

一种解决方案是,单击li后可以隐藏UI,但我真正想要的是关闭列表,即使用户未从列表中选择任何值也是如此。与下拉菜单的行为类似,但是由于某些样式原因,我无法使用下拉菜单。

我也不能使用 bootstrap 或JQueryUI之类的库

JSFiddle link

最佳答案

这是一个可能的解决方案。我添加了第二个observable,并在isSelected更改为false时引入了延迟

self.isSelected = ko.observable(false);
self.isVisible = ko.observable(false);

self.isSelected.subscribe(function(val) {
  if (val) {
    self.isVisible(true);
  } else {
    setTimeout(function() {
      self.isVisible(false);
    }, 300);
  }
});

LIVE DEMO

上面的缺点是mouseup需要在时限内发生。另一种方法是绑定(bind)到mousedown而不是click
<li data-bind="text: $data, event: {mousedown: function () { $root.Name($data); }}"></li>

10-07 19:34
查看更多