Javascript 对于knockout和json列表,如何为列表中的每个项目显示复选框,然后仅在选中时显示它

Javascript 对于knockout和json列表,如何为列表中的每个项目显示复选框,然后仅在选中时显示它,javascript,knockout.js,Javascript,Knockout.js,以下是一个不起作用的版本: <div data-bind="template: {name: 'checkbox-template', foreach: timeframes}"></div> <script type="text/html" id="checkbox-template"> <div><input type="ch

以下是一个不起作用的版本:

 <div data-bind="template: {name: 'checkbox-template', foreach: timeframes}"></div>

        <script type="text/html" id="checkbox-template">
            <div><input type="checkbox" data-bind="checked: $data, attr: {value: $data}" /><div data-bind="text: $data"></div></div>
        </script>


        <p>In bar format:</p>
        <canvas class="graph" id="overallBarChart"></canvas>


        <div data-bind="template: { name: 'stat-template', foreach: statsDisplay }"></div>

        <script type="text/html" id="stat-template">
            <h3 data-bind="text: chartname"></h3>
            <div style="height:300px"><canvas class="graph" data-bind="attr: {id: chartname}"></canvas></div>
        </script>

        <script>
             statistics = JSON.parse('{"Intimacy": {"03/09/2020": 1.0, "02/10/2020": 4.0, "04/11/2020": 7.0}, "Community": {"03/09/2020": 2.0, "02/10/2020": 4.0, "04/11/2020": 2.0}}');
            function AppViewModel() {
                var self = this;
                self.stats = ko.observableArray([]);
                Object.keys(statistics).forEach(function(key) {
                    self.stats.push({chartname: key, datesAndValues: statistics[key]});
                });
                console.log(self.stats());
                self.timeframes=ko.observableArray([]);
                console.log("timeframes before")
                console.log(self.timeframes());
                self.statsDisplay = ko.observableArray();
                self.sd = self.timeframes.subscribe(function(timeframes){
                    out=[];
                    console.log("running subscribe")
                    console.log(self.stats())
                    for (category in Object.keys(self.stats())){
                        out[category]= {};
                        out[category]["chartname"] = self.stats()[category]["chartname"];
                        out[category]["datesAndValues"] = {};
                    }
                    for (category in Object.keys(self.stats())){
                        for (time in self.timeframes()){
                            out[category]["datesAndValues"][time]={}
                        }
                    }
                    for (category in self.stats()){
                        cat=category
                        category=self.stats()[category]
                        console.log("in last cat loop")
                        console.log(cat)
                        console.log(category)
                        for (stattime in category["datesAndValues"]){
                            console.log("stattiem loop")
                            console.log(stattime)
                            for (tftime in self.timeframes()){
                                tftime=self.timeframes()[tftime]
                                console.log("various inside timeframes loop")
                                console.log(tftime)
                                console.log(stattime)
                                if (tftime === stattime){
                                    console.log("slkdnsndclskdn")
                                    console.log(category["datesAndValues"][tftime])
                                    out[cat]["datesAndValues"][tftime] = self.stats()[cat]["datesAndValues"][tftime]
                                };
                            };
                        };
                    };
                    console.log(out)
                    self.statsDisplay(out);
                }, null, 'arrayChange');
                Object.keys(self.stats()[0]["datesAndValues"]).forEach(function (key){
                    self.timeframes.push(key);
                });
            };

            var st = new AppViewModel();

            ko.applyBindings(st);

条形图格式:

statistics=JSON.parse({“亲密关系”:{“03/09/2020”:1.0,“02/10/2020”:4.0,“04/11/2020”:7.0},“社区”:{“03/09/2020”:2.0,“02/10/2020”:4.0,“04/11/2020”:2.0}); 函数AppViewModel(){ var self=这个; self.stats=ko.observearray([]); Object.keys(统计).forEach(函数(键){ self.stats.push({chartname:key,datesAndValues:statistics[key]}); }); log(self.stats()); self.timeframes=ko.observearray([]); console.log(“之前的时间范围”) console.log(self.timeframes()); self.statsDisplay=ko.observatarray(); self.sd=self.timeframes.subscribe(函数(timeframes){ out=[]; 日志(“正在运行的订阅”) console.log(self.stats()) for(Object.keys(self.stats())中的类别){ out[category]={}; out[category][“chartname”]=self.stats()[category][“chartname”]; out[category][“datesAndValues”]={}; } for(Object.keys(self.stats())中的类别){ for(self.timeframes()中的时间){ out[类别][“日期和值”][时间]={} } } for(self.stats()中的类别){ 类别 category=self.stats()[category] console.log(“在最后一个cat循环中”) 控制台日志(cat) console.log(类别) 对于(类别[“日期和值”]中的状态时间){ console.log(“statItem循环”) console.log(stattime) for(tftime在self.timeframes()中){ tftime=self.timeframes()[tftime] log(“各种内部时间框架循环”) console.log(tftime) console.log(stattime) 如果(tftime==stattime){ console.log(“slkdnsndclskdn”) console.log(类别[“datesAndValues”][tftime]) out[cat][“datesAndValues”][tftime]=self.stats()[cat][“datesAndValues”][tftime] }; }; }; }; console.log(注销) 自我状态显示(输出); },null,'arrayChange'); Object.keys(self.stats()[0][“datesAndValues”]).forEach(函数(键){ self.timeframes.push(按键); }); }; var st=新的AppViewModel(); ko.应用绑定(st);
我试图只显示复选框中选择的日期,我一直在下降,因为for循环似乎随机返回一个数字或对象的键


我的逻辑是通过循环,将统计数据中的时间与时间框架变量中的时间进行比较,形成订阅上的新可见时间框架,该时间框架在加载时填充,并在选择时更改。

啊,使用淘汰和嵌套对象的乐趣

在这种情况下,您可以在视图模型上使用两个变量:一个保存所有数据,另一个只保存选定数据。由于您使用的是对象,因此需要添加一些逻辑,用正确的键填充“selected data”变量

function ViewModel() {
  var vm = this;
  
  vm.statistics = ko.observable({});
  vm.selectedStatistics = ko.observable({});
  
  vm.init = function () {
    // This is our data; it probably comes from an API
    const statistics = JSON.parse('{"Intimacy": {"03/09/2020": 1.0, "02/10/2020": 4.0, "04/11/2020": 7.0}, "Community": {"03/09/2020": 2.0, "02/10/2020": 4.0, "04/11/2020": 2.0}}');

    // We have to add the keys to selectedStatistics
    // There, we store the selected values in an observableArray
    const stats = Object.keys(statistics);
    let i = stats.length;
    while (i--) {
        const selected = vm.selectedStatistics();
        selected[stats[i]] = ko.observableArray();
        vm.selectedStatistics(selected);
    }
    
    vm.statistics(statistics);
  }
  
  vm.init();
}
这将显示您的复选框和选定的复选框:

<h3>
 Statistics
</h3>

<!-- ko foreach: { data: Object.keys(statistics()), as: 'stat' } -->
<h4 data-bind="text: stat"></h4>
<ul data-bind="foreach: Object.keys($parent.statistics()[stat])">
  <li>
    <input type="checkbox" data-bind="checked: $parents[1].selectedStatistics()[stat], checkedValue: $data, attr: { id: [stat, $index()].join('-')  }">
    <label data-bind="text: $data + ': ' + $parents[1].statistics()[stat][$data], attr: { for: [stat, $index()].join('-') }"></label>
  </li>
</ul>
<!-- /ko -->

<h3>
Selected statistics
</h3>
<!-- ko foreach: { data: Object.keys(selectedStatistics()), as: 'stat' } -->
<h4 data-bind="text: stat"></h4>
<ul data-bind="foreach: $parent.selectedStatistics()[stat]">
  <li data-bind="text: $data"></li>
</ul>
<!-- /ko -->

统计
选定的统计数据

小提琴手:

谢谢您的回复!这是否意味着选中或取消选中复选框时不会更新init函数?到目前为止,我已经转移到服务器端,但是有了一些建议,我可能会后退。不。当复选框被选中/取消选中时,
checked
绑定将负责更新
selectedStatistics
变量,如您在小提琴中所看到的。谢谢!考虑到你的回答,我将再次尝试这一点。