Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript n级深复选框树行为_Javascript_Knockout.js - Fatal编程技术网

Javascript n级深复选框树行为

Javascript n级深复选框树行为,javascript,knockout.js,Javascript,Knockout.js,我使用knockout实现了一个n级复选框树,其中父级复选框的选择应该选择它的子级(但不是相反),一旦提交了数据,所选元素的ID应该转换为JSON发送到服务器 我不知道如何处理单向复选框关系,也不知道如何以这样的方式过滤我的最终json: 如果选择了一个父对象(这意味着它的所有子对象也被选择),则不在json中发送其子ID 仅选择一个或几个子项时如何不发送父项id 列表项的模型为: marketingListsItem = function (data, parent) { va

我使用knockout实现了一个n级复选框树,其中父级复选框的选择应该选择它的子级(但不是相反),一旦提交了数据,所选元素的ID应该转换为JSON发送到服务器

我不知道如何处理单向复选框关系,也不知道如何以这样的方式过滤我的最终json:

  • 如果选择了一个父对象(这意味着它的所有子对象也被选择),则不在json中发送其子ID

  • 仅选择一个或几个子项时如何不发送父项id

  • 列表项的模型为:

    marketingListsItem = function (data, parent) {
            var self = this;
            self.Name = ko.observable(data.Name);
            self.Selected = ko.observable(data.Selected);
            self.Parent = ko.observable(parent);
            self.Children = ko.observableArray([]);
            self.Id = ko.observable(data.Id);         
            self.DateAdded = ko.observable(new Date(data.DateAdded));
            self.DateModified = ko.observable(data.DateModified);
            if (data.Children) {
                ko.utils.arrayForEach(data.Children, function (child) {
                    self.Children.push(new marketingListsItem(child, this));
                }.bind(this));
            };
        }
    
    以下是“视图模型”部分:

    marketingListsViewModel = {
            marketingLists: mapping.fromJS([]),
            originatorConnectionName: ko.observable(''),
            selectedMarketingListIds: ko.observableArray([])
        },
        init = function (connectionId, connectionName) {
            marketingListsViewModel.originatorConnectionName(connectionName);
            marketingListsViewModel.getFieldMapping = function () {
                require(['mods/fieldmapping'], function (fieldmapping) {
                    fieldmapping.init(connectionId, connectionName);
                });
            };
            // Here I only managed to filter the parent level selections
            marketingListsViewModel.selectedLists = ko.computed(function () {
                return ko.utils.arrayFilter(marketingListsViewModel.marketingLists(), function (item) {
                    return item.Selected() == true;
                });
            });
            marketingListsViewModel.saveMarketingListChanges = function () {
                // Which I can filter my JSON to include them but the children are missing
                var latestMarketingListChanges = ko.toJSON(marketingListsViewModel.selectedLists, ["Id"]);
                console.log(latestMarketingListChanges);
                amplify.request("updateExistingMarketingLists", { cid: connectionId, ResponseEntity: { "id": connectionId, "selectedMarketListIds": latestMarketingListChanges } },
                    function (data) {
                        console.log(data);
                    });
            }
            amplify.request("getExistingMarketingLists", { cid: connectionId }, function (data) {
                showMarketingLists();
                mapping.fromJS(data.ResponseEntity, dataMappingOptions, marketingListsViewModel.marketingLists);
                ko.applyBindings(marketingListsViewModel, $('#marketingLists')[0]);
            });
        };
    
    最后一个观点是:

    <div id="marketingListsContainer">
            <ul data-bind="template: {name: 'itemTmpl' , foreach: marketingLists}"></ul>
            <script id="itemTmpl" type="text/html">
                <li>
                    <label><input type="checkbox" data-bind="checked: Selected" /><span data-bind='text: Name'></span></label>                    
                <ul data-bind="template: { name: 'itemTmpl', foreach: Children }" class="childList"></ul>
            </script>
        </div>
        <a class="s_button modalClose right" href="#"><span data-bind="click: saveMarketingListChanges">Save and close</span></a><br>
    
    
    


      • 您可以向所选绑定添加订阅事件,并执行类似操作,在检查父项时将所有子项标记为选中

        self.Selected.subscribe( function ( newValue ) {
            if ( newValue === true ) { 
                for ( i=0; i<self.Children().length; i++) {
                    self.Children()[i].Selected(true);
                }
            }
            else {
                 if ( self.Parent() != null ) { 
                     self.Parent().Selected(false);
                 }
            }
        } ) ;
        
        self.Selected.subscribe(函数(newValue)){
        如果(newValue==true){
        
        对于(i=0;i感谢您的回答。问题是,现在使用您的解决方案时,如果一个父级已通过服务器的数据进行了检查,则其子级的检查值不会发生变化

        我已将以下内容添加到模型中以解决此问题:

        self.sync = ko.computed(function () {
               return self.Selected.valueHasMutated();
        });
        
        对于稍后将找到此帖子并希望了解最终结果的人:

            define('mods/marketinglists', ["knockout", "libs/knockout.mapping", "libs/knockout.validation", "datacontext", "mods/campaigner", "text!templates/marketinglists.html", "text!styles/marketinglists.css"],
        function (ko, mapping, validation, datacontext, campaigner, html, css) {
            'use strict';
            var
                marketingListsItem = function (data, parent) {
                    var self = this;
                    self.Name = ko.observable(data.Name);
                    self.Selected = ko.observable(data.Selected);
                    self.Parent = ko.observable(parent);
                    self.Children = ko.observableArray([]);
                    self.Id = ko.observable(data.Id);
                    self.DateAdded = ko.observable(new Date(data.DateAdded));
                    self.DateModified = ko.observable(data.DateModified);
                    // If node contains children define each one as a marketingListItem in itself
                    // and bind it to the the model
                    if (data.Children) {
                        ko.utils.arrayForEach(data.Children, function (child) {
                            self.Children.push(new marketingListsItem(child, this));
                        }.bind(this));
                    };
                    // Watch for value changes in parent and check children 
                    // if the parent was checked
                    self.Selected.subscribe(function (newValue) {
                        if (newValue === true) {
                            for (var i = 0; i < self.Children().length; i++) {
                                self.Children()[i].Selected(true);
                            }
                        }
                        else {
                            if (self.Parent() != null) { self.Parent().Selected(false); }
                        }
                    });
                    // Make sure subscribers have been notified when needed
                    self.sync = ko.computed(function () {
                        return self.Selected.valueHasMutated();
                    });
                },
                dataMappingOptions = {
                    key: function (data) {
                        return data.Id;
                    },
                    create: function (options) {
                        return new marketingListsItem(options.data, null);
                    }
                },
                showMarketingLists = function () {
                    campaigner.addStylesToHead(css);
                    campaigner.addModalWindow(html, {
                        windowSource: "inline",
                        width: 700,
                        height: '340'
                    });
                },
                marketingListsViewModel = {},
                init = function (connectionId, connectionName) {
                    // Define marketingLists as an observable array from JS object
                    marketingListsViewModel.marketingLists = mapping.fromJS([]);
                    marketingListsViewModel.originatorConnectionName = ko.observable('');
                    // Set the name for the marketing list
                    marketingListsViewModel.originatorConnectionName(connectionName);
                    marketingListsViewModel.getFieldMapping = function () {
                        require(['mods/fieldmapping'], function (fieldmapping) {
                            fieldmapping.init(connectionId, connectionName);
                        });
                    };
                    marketingListsViewModel.selectedLists = ko.computed(function () {
                        var selectedItems = [];
                        ko.utils.arrayFilter(
                            marketingListsViewModel.marketingLists(),
                            function (item) {
                                // If a parent a selected its being collected
                                if (item.Selected() == true) selectedItems.push(item);
                                else {
                                    // If a child is slected it is collected
                                    ko.utils.arrayForEach(item.Children(), function (child) {
                                        if (child.Selected()) selectedItems.push(child);
                                        else {
                                            ko.utils.arrayForEach(child.Children(),
                                                // Finally if children's child is selected its collected
                                                function (childChildren) {
                                                    if (childChildren.Selected())
                                                        selectedItems.push(childChildren);
                                                });
                                        }
                                    })
                                }
                            });
                        return selectedItems;
                    });
                    marketingListsViewModel.saveMarketingListChanges = function () {
                        // Pick only the selected elements and parse only the Id
                        var latestMarketingListChanges = ko.toJSON
                            (marketingListsViewModel.selectedLists,
                                ["Id"]);
                        console.log(latestMarketingListChanges);
                        // Send the latest marketing lists changes Ids to the server
                        amplify.request("updateExistingMarketingLists",
                            {
                                cid: connectionId,
                                ResponseEntity:
                                {
                                    "id": connectionId,
                                    "selectedMarketListIds": latestMarketingListChanges
                                }
                            },
                            function (data) {
                                console.log(data);
                            });
                    }
                    amplify.request("getExistingMarketingLists", { cid: connectionId },
                        function (data) {
                            showMarketingLists();
                            mapping.fromJS(
                                data.ResponseEntity,
                                dataMappingOptions,
                                marketingListsViewModel.marketingLists);
        
                            ko.applyBindings(marketingListsViewModel, $('#marketingLists')[0]);
                        });
                };
            return {
                init: init,
                marketingListsViewModel: marketingListsViewModel,
                html: html,
                css: css
            }
        });
        
        <div id="marketingListsContainer">
                    <ul data-bind="template: {name: 'itemTmpl' , foreach: marketingLists}"></ul>
                    <script id="itemTmpl" type="text/html">
                        <li>
                            <!-- ko if: $data.Parent -->
                            (my parent is: <span data-bind="text: $data.Parent().Name"></span>) 
                            <!-- /ko -->
                            <label><input type="checkbox" data-bind="checked: Selected" /><span data-bind='text: Name'></span></label>                    
                        <ul data-bind="template: { name: 'itemTmpl', foreach: Children }" class="childList"></ul>
                    </script>
                </div>
                <a class="s_button modalClose right" href="#"><span data-bind="click: saveMarketingListChanges">Save and close</span></a><br>
        
        define('mods/marketinglists',[“knockout”,“libs/knockout.mapping”,“libs/knockout.validation”,“datacontext”,“mods/activater”,“text!templates/marketinglists.html”,“text!style/marketinglists.css”],
        功能(ko、映射、验证、datacontext、活动家、html、css){
        "严格使用",;
        变量
        marketingListsItem=功能(数据,父项){
        var self=这个;
        self.Name=ko.observable(data.Name);
        self.Selected=可观察的ko(数据选择);
        自我父母=可观察(父母);
        自我儿童=ko.observearray([]);
        self.Id=ko.observable(data.Id);
        self.DateAdded=ko.observable(新日期(data.DateAdded));
        self.DateModified=ko.可观察(data.DateModified);
        //如果节点包含子节点,则将每个子节点本身定义为marketingListItem
        //并将其绑定到模型
        if(数据子项){
        ko.utils.arrayForEach(data.Children,function(child)){
        self.Children.push(new marketingListsItem(child,this));
        }.约束(这个);
        };
        //注意父项中的值更改并检查子项
        //如果选中了父项
        self.Selected.subscribe(函数(newValue)){
        如果(newValue==true){
        for(var i=0;i<div id="marketingListsContainer">
                    <ul data-bind="template: {name: 'itemTmpl' , foreach: marketingLists}"></ul>
                    <script id="itemTmpl" type="text/html">
                        <li>
                            <!-- ko if: $data.Parent -->
                            (my parent is: <span data-bind="text: $data.Parent().Name"></span>) 
                            <!-- /ko -->
                            <label><input type="checkbox" data-bind="checked: Selected" /><span data-bind='text: Name'></span></label>                    
                        <ul data-bind="template: { name: 'itemTmpl', foreach: Children }" class="childList"></ul>
                    </script>
                </div>
                <a class="s_button modalClose right" href="#"><span data-bind="click: saveMarketingListChanges">Save and close</span></a><br>