Knockout - 具有subscribe doenst的Observable数组似乎可以工作

时间:2017-09-18 16:58:04

标签: javascript jquery arrays checkbox knockout.js

抱歉这个冗长的问题。我是knockout.js的新手。

我的商业案例 我有一个面板,在foreach循环中有两个复选框(是/否)。对于某些项目组,当选中一个项目并选中“是”复选框时,我需要取消选中该组中其他项目的“是”复选框,并选中这些项目的“否”复选框。

  1. 我正在使用与可观察数组绑定的checked事件(在单独的可观察数组中是/否)。
  2. 项目按属性分组。(我的商业案例)
  3. 一个Observable数组将保留“是”选定项目。
  4. 另一个可观察数组将保留“否”选定项目。
  5. 我有'Yes'可观察数组的订阅方法。
  6. 在内部我有逻辑删除已从此可观察数组中选择“是”的组中的项目。
  7. 当用户'检查'复选框时调用subscribe函数,并且由于我在上面第6点中解释的逻辑而在subscribe方法中更改了可观察数组时也调用了该函数。

    问题:事情似乎工作得很好,我可以通过开发人员工具进行调试,但是当执行删除已经选择的值的逻辑时,它不会反映在UI中。复选框仍然会为组中的多个项目选择“是”。

    例如:当在组中选择了其中一个项目的“是”复选框时,必须取消选中组中其他项目“是”复选框。这似乎反映在变量值中,但UI显示其他项目仍然选中“是”复选框。

    包含“是”所选项目的My Observable数组仍会在其中显示正确的值(在控制台中),但UI显示多个项目选择了“是”。

    请告诉我这里的问题。

    HTML:

    <div data-bind="template: { name: 'ItemTemplate', foreach: Items }"></div>
    <script type="text/html" id="ItemTemplate">
    <!-- Other Html stuffs -->
    
        <div id="SelectionPanel" class="SelectionPanel checkStyle">
                                    <label>
                                        <input type="checkbox" data-bind="value: Id(), click: $root.PersistAutoSelection, checked: $root.SelectedItem, attr: { 'class': SelectStyle, id: 'itemPanelSelected' + $index(), name: 'SelectedIds'}" />
                                        <label data-bind="attr: { 'for': 'PanelSelected' + $index() }">
                                            <p>Yes</p>
                                        </label>
                                    </label>
                                </div>
    
                                <div id="NotRequiredPanel">
                                    <div class="checkbox checkStyle">
                                        <input type="checkbox" class="not-required" data-bind="value: Id(), click: $root.Deselect.bind($data, Id().toString()),checked: $root.NotRequired,attr: { id: 'PanelNotRequired' + $index(), name: 'NotRequiredIds' }" />
                                        <label data-bind="attr: { 'for': 'PanelNotRequired' + $index() }">
                                            <p>No</p>
                                        </label>
                                    </div>
                                </div>
    
    
    </script>
    

    Knockout.js脚本:

    var currentlySelectedObject = null;
    var isExcessModified = false;
        function ViewModel() {
                var self = this;
                self.SelectedItem = ko.observableArray([]);
                self.NotRequired = ko.observableArray([]);             
                self.Select = function (index) {
                    self.SelectedItem.push(index.toString());
                }
    
            self.Deselect = function (index) {
    
                self.SelectedItem.remove(index.toString());
                self.NotRequired.remove(index.toString());
                self.NotRequired.push(index.toString());                
                return true;
            }
    
            self.SelectedItem.subscribe(function (newValue) {
                var unselectedItem = ko.utils.arrayMap(self.Items(), function (item) {
                    return item.Id().toString();
                });
                ko.utils.arrayForEach(self.SelectedItem(), function (itemId) {                
                    ko.utils.arrayRemoveItem(unselectedItem , itemId.toString());
                });           
                if (isExcessModified)
               self.ExcessProtectSelectValidation(currentlySelectedObject);
    
            });
    
            self.Remove = function (name) {
                ko.utils.arrayForEach(self.Items(), function (item) {
                    if (item.Name().toLowerCase() == name.toLowerCase()) {
    
                        var itemId = item.Id().toString();
                        self.SelectedItem.remove(itemId);
                        self.NotRequired.remove(itemId);
                    }
                });
            }
    
            self.PersistAutoSelection = function (data, event) {
                self.NotRequired.remove(data.Id().toString());
    
                if (!$('#itemPanelSelected' + data.Id().toString()).is(':checked'))
                    self.SelectedItem.remove(data.Id().toString());
    
               currentlySelectedObject = event.target;
               isExcessModified = true;
                return true;
            }
    self.ExcessProtectSelectValidation = function (obj) {
                isExcessModified = false;
                var yesNoPanel = $(obj).closest('div.bottom');
                var schId = $(obj).closest('div.bottom').prev().prev().find("[id^=SchemeID]").val();
                if (schId == "AC1" || schId == "AC2" || schId == "AC3") {
                    //Condition to choose any one of the item
                    if ($(obj).is(':checked')) {
                        if (isExcessSelected) {
                            var itemId = $(obj).closest('[id^="itemPanelInner"]').attr("panelId");
                            //Logic to remove error message for previous selection
                            $('*[id*=SchID]').each(function (index) {
                                if ($(this).val() != schCodeId && ($(this).val() == "AC1" || $(this).val() == "AC2" || $(this).val() == "AC3")) {
                                    Code to show tooltip here;
                                }
                            });
                            //Show error message if try to choose the more than one item had chosen
                            AddErrorToolTip(yesNoPanel, ToolTipContent);
                            self.NotRequired.push(itemId.toString());
                            self.SelectedItem.remove(itemId.toString());
    
                        }
                        else {
                            //Logic to deselect the other two item, if one the item is already selected
                            yesNoPanel.removeClass("ErrorHighlight");
                            yesNoPanel.qtip("destroy", true);
                            isExcessSelected = true;
                            if (schId == "AC1" || schId == "AC2" || schId == "AC3") {
                                $('*[id*=SchID]').each(function (index) {
                                    if ($(this).val() == "AC1" || $(this).val() == "AC2" || $(this).val() == "AC3") {
                                        var itemId = $(this).closest('[id^="itemPanelInner"]').attr("panelId");
                                        if ($(this).val() != schId && ($(this).val() == "AC1" || $(this).val() == "AC2" || $(this).val() == "AC3")) {
                                            var yesNoPanel = $(this).closest('div.top').next().next();
                                            yesNoPanel.removeClass("ErrorHighlight");
                                            yesNoPanel.qtip("destroy", true);
                                            self.NotRequired.push(itemId.toString());
                                            $('#itemPanelSelected' + itemId.toString()).attr('checked', false);
                                            self.SelectedItem.remove(itemId.toString());
                                        }
                                    }
    
                                })
                            }
                        }
                    }
                    else {
                        isExcessSelected = false;
                        $('*[id*=SchID]').each(function (index) {
                            if ($(this).val() == "AC1" || $(this).val() == "AC2" || $(this).val() == "AC3") {
                                if ($(this).closest("div.top").next().next().find('[id^="ItemPanelNotRequired"]').is(':checked')) {
                                    //Logic to remove the error message if already selected item is unselected
                                    if ($(this).closest('[id^="ItemPanelInner"]').find('div.bottom.ErrorHighlight').length > 0) {
                                        var errorAttachedPanel = $(this).closest('[id^="ItemPanelInner"]').find('div.bottom');
                                        errorAttachedPanel.removeClass("ErrorHighlight");
                                        errorAttachedPanel.qtip("destroy", true);
                                    }
                                }
                            }
                        })
    
                    }
    
                }
            }
    
    }
    

0 个答案:

没有答案