根据单选按钮显示不同(在Knockout中)

时间:2015-10-02 16:29:28

标签: javascript html knockout.js

好的,这里有。

问题1: 我想根据选中的单选按钮显示或不显示tr元素。 Threre将是3个按钮,显示'解锁成就'锁定'以及'全部' (都锁定+解锁)。

下面的代码显示了当我尝试调用三个不同的函数时的外观,每个函数根据选中的单选按钮将tr:s可见性设置为true / false。 (D.R.Y,我知道,但现在我只是在寻找功能)。

问题2: 使for循环运行。 itemsListForFilter在filter函数之外全局声明。 itemsListForFilter是对象arrayMap的副本,它初始化并在代码中的其他位置填充。该数组包含项目,其中包括布尔" radioCheck",默认值为" true",我要检查。

当我在复制发生的函数中访问itemsListForFilter时,它会填充项目但是...... 当我尝试在过滤器函数中访问itemsListForFilter时,它显示为具有null值。因此副本已经丢失了#34;某处:)

查看/ HTML:

<div class="widget-header-container">
                <h3 class="widget-header">Achievements</h3>
                <div class="wrapper">
                    <input type="radio" name="appliedFilter" value="all" data-bind="checked: filterAll"/><label for="all">Show all</label>
                    <input type="radio" name="appliedFilter" value="unlocked" data-bind="checked: filterUnlocked"/><label for="unlocked">Unlocked</label>
                    <input type="radio" name="appliedFilter" value="locked" data-bind="checked: filterLocked"/><label for="locked">Locked</label>
                </div>

                <div><div class="widget-header-line-game1"></div><div class="widget-header-line-game2"></div><div class="widget-header-line-shadow"></div></div>
            </div>
            <div>
                <div class="rounded-box" style="padding:15px;padding-top: 0;background-color:#fff;overflow:hidden;">
                    <table id="game-achievements" class="table table-condensed" style="margin-top:10px;">
                        <tbody data-bind="foreach: viewGame.achievements()">
                            <tr data-bind="visible: radioCheck" style="display: none">

Viewmodel / JS:

filterUnlocked: function(){
    return filter('unlocked');
},
filterLocked: function(){
    return filter('locked');
},
filterAll: function(){
    return filter('all');
},
filter: function(x){

    for (var item in itemsListForFilter){
        if (x === 'locked'){
            item.radioCheck = '!achieved';
        }
        if (x === 'unlocked') {
            item.radioCheck = 'achieved';
        }
        else {item.radioCheck = true;}
    }

观察viewmodel是一个对象而不是一个函数:

var gamesViewModel = {

self: this,
settings: null,
gameId: null,
authorized: false,
(...)

现在名为filterUnlocked等的函​​数(filter除外)显示为&#34;未使用的属性&#34;在JS文件中。我该怎么做才能从HTML中调用它们?或者有更好的方法来完成我正在寻找的东西吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以以更低的复杂度获得所需的效果。

首先是广播组。 Knockout中的checked绑定替换(或类似)无线电组的name属性:所有单选按钮应共享一个。绑定变量将更新为所选单选按钮的值,这将导致绑定到同一变量的其他变量取消选择。现在你有一个变量可以看而不是三个。

不是通过隐藏行进行过滤,而是通常使用computed过滤数据,而表格只显示它。计算出的数据可以从“外部”获取;它不必是可观察的或视图模型的一部分(尽管如果它不是可观察的,你需要告诉计算的更新时间,如果源更改)。

这是一个小小的工作示例:

var achievements = [{
  name: 'The locked one',
  locked: true
}, {
  name: 'The unlocked one',
  locked: false
}];
var vm = {
  appliedFilter: ko.observable('all'),
  viewGame: {}
};

vm.viewGame.achievements = ko.computed(function() {
  var filter = vm.appliedFilter();
  if (filter === 'all') {
    return achievements;
  }
  return ko.utils.arrayFilter(achievements, function(item) {
    return item.locked === (filter === 'locked');
  });
});

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="widget-header-container">
  <h3 class="widget-header">Achievements</h3>

  <div class="wrapper">
    <input type="radio" value="all" data-bind="checked: appliedFilter" />
    <label for="all">Show all</label>
    <input type="radio" value="unlocked" data-bind="checked: appliedFilter" />
    <label for="unlocked">Unlocked</label>
    <input type="radio" value="locked" data-bind="checked: appliedFilter" />
    <label for="locked">Locked</label>
  </div>
</div>
<div>
  <div class="rounded-box" style="padding:15px;padding-top: 0;background-color:#fff;overflow:hidden;">
    <table id="game-achievements" class="table table-condensed" style="margin-top:10px;">
      <tbody data-bind="foreach: viewGame.achievements()">
        <tr><td data-bind="text: name"></td></tr>
      </tbody>
    </table>
  </div>
</div>