KnockoutJS:处理选择框。选择默认值并删除现有项目

时间:2012-11-09 04:08:28

标签: javascript knockout.js

我无法处理Knockout JS中的复选框。

jsfiddle链接http://jsfiddle.net/wenbert/Xyuhk/72/

请注意,我为每个父级(Hero)提供了2个选择框。每个人都使用不同的方式,但两者都或多或少地“观察”同一个对象。

工作流

enter image description here

  1. 点击灰色框
  2. 应显示带有蓝色虚线的框,其中包含“选择”框的项目。
  3. 从这里,您可以编辑选择框的项目。
  4. 在这里小提琴:http://jsfiddle.net/wenbert/Xyuhk/72/
  5. 问题

    1. 当我删除某个项目时,我无法将其从“选择”框中删除。请注意,我不想将其从对象中完全删除。我只想将当前项目标记为“isDeleted”。
    2. 选择A - 隐藏项目,但在选择框中留下一个空选项。
    3. 选择B - “ifnot:isDeleted”对选项没有任何影响。
    4. 问题

      如何处理选择框?我已经以两种不同的方式呈现了2个选择框,以使ifnot: isDeleted生效,但它们都没有工作。

      更新:使用此设置,如何执行选择框的“已选择”值?

      HTML

      <button data-bind="click: addHero">Add Hero</button>
      <ul data-bind="foreach: heroes">
          <li class="parent" data-bind="ifnot: isDeleted, click: $parent.selectHero">
              <input class="big-box" type="text" data-bind="value: name" />
              <button class="btn-small" data-bind="click: $parent.removeHero">Remove Hero</button>
              <br/>
      
              SKILLS: 
      
              Select A) <select data-bind="foreach: skills">
                  <option data-bind="value: name, text: name, ifnot: isDeleted"></option>            
              </select>
              Select B) <select data-bind="options: skills, optionsText: 'name', value: selected_skill.name, ifnot: isDeleted">         
              </select>
              <br/>
              <span class="instructions">(Step 1: Click somewhere here)</span>
          </li>
      </ul>
      
      <div class="edit-panel" data-bind="if: selectedHero">
          Edit Skill:<br/>
          <div data-bind="with: selectedHero">
              <button class="btn-small" data-bind="click: addSkill">Add Skill</button>
              <ul data-bind="foreach: skills">
                  <li data-bind="ifnot: isDeleted">
                      <button class="btn-small" data-bind="click: $parent.setAsDefaultSkill">Set as default</button>
                      <input data-bind="value: name" />
                      <button class="btn-small" data-bind="click: $parent.removeSkill">Remove Skill</button>
                  </li>
              </ul>
              <span class="instructions">(Step 2: Remove a Skill, then have a look at the Select Box above.)</span>
          </div>
      </div>
      
      
      <pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
      

      的Javascript

      var initialData = [
          {
              id: '1',
              name: "Batman",
              isDelete: false,
              selected_skill: {name: "Boxing", isDeleted: false},
              skills: [
                  { id: '1', name: "Karate", isDeleted: false },
                  { id: '2', name: "Boxing", isDeleted: false},
                  { id: '6', name: "Sonar", isDeleted: false}
              ]
          },
          {
              id: '2',
              name: "Hulk",
              isDelete: false,
              skills: [
                  { id: '3', name: "MMA", isDeleted: false },
                  { id: '4', name: "Rage", isDeleted: false},
                  { id: '5', name: "Extra Strength", isDeleted: false}
              ]
          },
      ];
      
      
      function Hero(data) {
          var self = this;
          self.name = ko.observable(data.name);
          self.selected_skill= ko.observable(data.selected_skill);
          self.skills = ko.observableArray(ko.utils.arrayMap(data.skills, function(i) {
              return new Skills(i);
          }));
      
          self.addSkill = function() {
              self.skills.push(new Skills({name: '---', isDeleted: false}));
          }
      
          self.setAsDefaultSkill = function(item) {
              self.selected_skill(item);
          }
      
          self.isDeleted = ko.observable(data.isDeleted);
      
          self.removeSkill = function(item) {
              item.isDeleted(true);
          }
      }
      
      function Skills(data) {
          var self = this;
          self.name = ko.observable(data.name);
          self.isDeleted = ko.observable(data.isDeleted);
      }
      
      function SuperheroViewModel(data) {
          var self = this;
          self.heroes = ko.observableArray(ko.utils.arrayMap(data, function(i){
              return new Hero(i);
          }));
      
          self.selectedHero = ko.observable();
          self.selectedHero.skills = ko.observableArray();
      
          self.addHero = function() {
              self.heroes.push(
                  new Hero({
                      name: 'Wolverine',
                      isDelete: false,
                      skills: [{name: 'Breathing', isDeleted: false}],
                  })
              );
          }
      
          self.selectHero = function(item) {
              self.selectedHero(item);
          }
      
          self.removeHero= function(item) {
              item.isDeleted(true);
          }
      }
      
      ko.applyBindings(new SuperheroViewModel(initialData ));
      ​
      ​
      

      我希望一切都清楚。

      任何回复都将不胜感激。

      谢谢!

1 个答案:

答案 0 :(得分:1)

我会在viewmodel中进行过滤。所以我会创建一个像availableSkills

这样的过滤集合
self.availableSkills = ko.computed(function() {
    return ko.utils.arrayFilter(self.skills(), function(item) {
        return !item.isDeleted();
    })
});

然后我会在选择中使用它:

<select data-bind="foreach: availableSkills">
     <option data-bind="value: name, text: name"></option>            
</select>

Demo fiddle.