【问题标题】:knockout click binding - block binding on all elements except clicked element淘汰点击绑定 - 阻止对除点击元素之外的所有元素的绑定
【发布时间】:2018-01-21 13:23:26
【问题描述】:

我对淘汰赛中的点击绑定有疑问。我几乎找到了解决方案,但仍然不是我想要的。我为两个列表使用模板(模板相同)。在列表中,我几乎没有具有相同绑定的元素,在开始时我可以单击任何按钮,但是当我单击某个元素时,我想阻止仅从一个列表中选择/单击其他项目的能力。示例将更好地解释: JS

function AppViewModel() {
    var self = this;
    self.people = ko.observableArray([
        { name: 'Bert', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' },
        { name: 'Charles', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' },
        { name: 'Denise', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' }
    ]);
    self.workers = ko.observableArray([
        { name: 'Bart', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' },
        { name: 'Joey', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' },
        { name: 'Daniel', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' }
    ]);
    self.checkVoice = function() {
      console.log('test');
    };
}

ko.applyBindings(new AppViewModel());

HTML

<h2>List one</h2>
<div data-bind="template: { name: 'person', data: people }"></div>
<h2>List two</h2>
<div data-bind="template: { name: 'person', data: workers }"></div>

<script type="text/html" id="person">
    <!-- ko foreach: $data -->
    <div data-bind="text: $data.name"></div>
    <button data-bind="click: $root.checkVoice">like</button>
    <button data-bind="click: $root.checkVoice">dislike</button>
    <!-- /ko --> 
</script>

link to fiddle

我的目标是:当我单击“Bert”名称的“赞”按钮时,我想关闭单击此列表中的其他按钮的可能性,但我希望在第二个列表中具有完全相同的可能性。 仅使用一个模板可以做到这一点吗? 现在我有这样的东西:

data-bind="click: function(data, event, type) { if(buttonClickedObservable()) { $root.checkAvailability($data, event, 'standard'); } }"

这个解决方案还不错,但关闭了点击两个列表的可能性,而不仅仅是一个

【问题讨论】:

    标签: javascript jquery knockout.js


    【解决方案1】:

    我有点难以理解您的要求。但也许一个组件而不是模板可能更适合您的需求。使用组件,您可以获得模板和视图模型。

    这是一个小提琴https://jsfiddle.net/odygrxt8/4/

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

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

    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>'
    });
    

    【讨论】:

    • 谢谢布莱恩,这有点帮助。我将尝试解释为什么我需要阻止按钮。在我的项目中,我必须列出航空公司中的示例,第一个列表用于以一种方式旅行,第二个列表用于返回方式(如果存在)。对于单程和返回方式,我使用相同的模板写入脚本标记(这是必要的)。列表显示所选日期的门票,例如 10 个结果。一个结果有 3 个经济舱、商务舱和头等舱。用户只能从所有结果中选择一个类。当单击连接到单击绑定的按钮功能时,检查此票的可用性。
    【解决方案2】:

    这是使用自定义绑定完成此任务的一个选项:

    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 });
      }
    }
    

    绑定使用“组”来跟踪哪些按钮共享相同的状态,在这种情况下,该组是父数组。然后绑定将一个可观察对象附加到父数组以存储状态,并将同一组数组中的所有元素绑定到该可观察对象。

    function AppViewModel() {
        var self = this;
        self.people = ko.observableArray([
            { name: 'Bert', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' },
            { name: 'Charles', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' },
            { name: 'Denise', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' }
        ]);
        self.workers = ko.observableArray([
            { name: 'Bart', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' },
            { name: 'Joey', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' },
            { name: 'Daniel', bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' }
        ]);
        self.checkVoice = function() {
          console.log('test');
        };
    }
    
    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 });
      }
    }
     
    ko.applyBindings(new AppViewModel());
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <h2>List one</h2>
    <div data-bind="template: { name: 'person', data: people }"></div>
    <h2>List two</h2>
    <div data-bind="template: { name: 'person', data: workers }"></div>
    
    <script type="text/html" id="person">
        <!-- ko foreach: $data -->
        <div data-bind="text: $data.name"></div>
        <button data-bind="groupClick: $root.checkVoice, groupKey: $parent">like</button>
        <button data-bind="groupClick: $root.checkVoice, groupKey: $parent">dislike</button>
        <!-- /ko --> 
    </script>
    <script type="text/html" id="person">
        <!-- ko foreach: $data -->
        <div data-bind="text: $data.name"></div>
        <button data-bind="groupClick: $root.checkVoice, groupKey: $parent">like</button>
        <button data-bind="groupClick: $root.checkVoice, groupKey: $parent">dislike</button>
        <!-- /ko --> 
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多