Javascript 敲除单击绑定-对除单击元素以外的所有元素进行块绑定

Javascript 敲除单击绑定-对除单击元素以外的所有元素进行块绑定,javascript,jquery,knockout.js,Javascript,Jquery,Knockout.js,我对敲除中的单击绑定有疑问。我几乎找到了解决办法,但仍然不是我想要的。我将模板用于两个列表(模板相同)。在一个列表中,我有几个元素具有相同的绑定,在开始时,我可以单击任何按钮,但当我单击某个元素时,我想阻止仅从一个列表中选择/单击其他项目的功能。举例说明更好: JS HTML 这个解决方案不错,但是关闭了在两个列表上单击的可能性,而不仅仅是在一个列表上单击。我在理解您的需求方面有点困难。但是,也许一个组件而不是一个模板可以更好地满足您的需要。通过一个组件,您可以得到一个模板和一个viewmode

我对敲除中的单击绑定有疑问。我几乎找到了解决办法,但仍然不是我想要的。我将模板用于两个列表(模板相同)。在一个列表中,我有几个元素具有相同的绑定,在开始时,我可以单击任何按钮,但当我单击某个元素时,我想阻止仅从一个列表中选择/单击其他项目的功能。举例说明更好: JS

HTML


这个解决方案不错,但是关闭了在两个列表上单击的可能性,而不仅仅是在一个列表上单击。我在理解您的需求方面有点困难。但是,也许一个组件而不是一个模板可以更好地满足您的需要。通过一个组件,您可以得到一个模板和一个viewmodel

这是一把小提琴

同样,我不太理解您关于禁用按钮的要求,但如果您运行小提琴,则在任何给定列表中只有一个“喜欢”或“不喜欢”处于活动状态

这是您可能需要更改逻辑以满足实际需求的组件,但希望它能给您一个想法

ko.components.register('like-widget', {
  viewModel: function(params) {
    var self = this;
    this.data = params.value;
    this.selectedName = ko.observable('');
    this.choice = ko.observable('');
    this.likeIt = function(row) {
      self.selectedName(row.name);
      self.choice('like');
    };
    this.dislikeIt = function(row) {
      self.selectedName(row.name);
      self.choice('dislike');
    };
  },
  template: ' <div data-bind="foreach: data">\
           <div data-bind="text: $data.name"></div>\
            <button data-bind="click: $parent.likeIt, css: {\'btn-danger\': ($data.name == $parent.selectedName() && $parent.choice() == \'like\')}" class="btn">like</button>\
             <button data-bind="click: $parent.dislikeIt, css: {\'btn-warning\': ($data.name == $parent.selectedName() && $parent.choice() == \'dislike\')}" class="btn">Dislike</button>\
         </div>'
});
ko.components.register('like-widget'{
viewModel:函数(参数){
var self=这个;
this.data=params.value;
this.selectedName=ko.observable(“”);
this.choice=ko.可观察(“”);
this.likeIt=函数(行){
self.selectedName(行名称);
自我选择(“喜欢”);
};
this.dislikeIt=函数(行){
self.selectedName(行名称);
自我选择(“厌恶”);
};
},
模板:'\
\
像\
不喜欢\
'
});

这里有一个选项可以使用自定义绑定完成此操作:

ko.bindingHandlers.groupClick = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    var accessor = valueAccessor();
    var groupKey = allBindings().groupKey;    
    groupKey._groupClicked = groupKey._groupClicked || ko.observable(false);

    $(element).click(function(){
        groupKey._groupClicked(true);
    });

    var canClick = ko.computed(function(){
        return !groupKey._groupClicked();
    });
    var fontColor = ko.computed(function(){
        return { color: canClick() ? 'black' : 'silver' };
    });
    ko.applyBindingsToNode(element, { enable: canClick, style: fontColor });
  }
}
绑定使用“组”来跟踪哪些按钮共享相同的状态,在本例中,该组是父数组。然后绑定将一个可观察对象附加到父数组以存储状态,并将同一组数组中的所有元素绑定到该可观察对象

函数AppViewModel(){
var self=这个;
self.people=ko.array([
{姓名:'Bert',简历:'Lorem ipsum dolor sit amet,Concertetur adipiscing Elite'.},
{姓名:'Charles',简历:'Lorem ipsum dolor sit amet,Concertetur adipiscing Elite'.},
{姓名:'Denise',简历:'Lorem ipsum dolor sit amet,Concetetur adipiscing Elite'.}
]);
self.workers=ko.array([
{姓名:'Bart',简历:'Lorem ipsum dolor sit amet,Concetetur Adipising Elite'.},
{姓名:'Joey',简历:'Lorem ipsum dolor sit amet,Concetetur adipiscing Elite'.},
{姓名:'Daniel',简历:'Lorem ipsum dolor sit amet,Concertetur adipiscing Elite'.}
]);
self.checkVoice=函数(){
console.log('test');
};
}
ko.bindingHandlers.groupClick={
init:函数(元素、valueAccessor、allBindings、viewModel、bindingContext){
var accessor=valueAccessor();
var groupKey=allBindings().groupKey;
groupKey._groupClicked=groupKey._groupClicked | | ko.可观察(false);
$(元素)。单击(函数(){
groupKey.\u groupClicked(true);
});
var canClick=ko.computed(函数(){
return!groupKey.\u groupClicked();
});
var fontColor=ko.computed(函数(){
返回{color:canClick()?'black':'silver'};
});
applybindingstoode(元素,{enable:canClick,style:fontColor});
}
}
应用绑定(新的AppViewModel())

清单一
清单二
喜欢
不喜欢

谢谢,布莱恩,这有点帮助。我将尝试解释为什么我需要阻止按钮。在我的项目中,我必须列出航空公司的例子,第一个列表用于以一种方式旅行,第二个列表用于返回方式(如果存在)。对于单向和返回方式,我使用相同的模板写入脚本标记(这是必要的)。列表显示所选日期的票证,示例10结果。一个成绩分为经济、商业和第一三级。用户只能从所有结果中选择一个类。当点击按钮功能连接到点击绑定检查此票的可用性。
data-bind="click: function(data, event, type) { if(buttonClickedObservable()) { $root.checkAvailability($data, event, 'standard'); } }"
ko.components.register('like-widget', {
  viewModel: function(params) {
    var self = this;
    this.data = params.value;
    this.selectedName = ko.observable('');
    this.choice = ko.observable('');
    this.likeIt = function(row) {
      self.selectedName(row.name);
      self.choice('like');
    };
    this.dislikeIt = function(row) {
      self.selectedName(row.name);
      self.choice('dislike');
    };
  },
  template: ' <div data-bind="foreach: data">\
           <div data-bind="text: $data.name"></div>\
            <button data-bind="click: $parent.likeIt, css: {\'btn-danger\': ($data.name == $parent.selectedName() && $parent.choice() == \'like\')}" class="btn">like</button>\
             <button data-bind="click: $parent.dislikeIt, css: {\'btn-warning\': ($data.name == $parent.selectedName() && $parent.choice() == \'dislike\')}" class="btn">Dislike</button>\
         </div>'
});
ko.bindingHandlers.groupClick = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    var accessor = valueAccessor();
    var groupKey = allBindings().groupKey;    
    groupKey._groupClicked = groupKey._groupClicked || ko.observable(false);

    $(element).click(function(){
        groupKey._groupClicked(true);
    });

    var canClick = ko.computed(function(){
        return !groupKey._groupClicked();
    });
    var fontColor = ko.computed(function(){
        return { color: canClick() ? 'black' : 'silver' };
    });
    ko.applyBindingsToNode(element, { enable: canClick, style: fontColor });
  }
}