加载列表取决于淘汰赛中的类别

时间:2017-06-08 09:14:53

标签: knockout.js

尝试制作一个小应用程序 有类别(地方,咖啡店,俱乐部)

如何在淘汰赛中加载相应类别的列表。

如何加载标签列表(仅一次)并且可点击并在点击时加载标签列表

这是我的代码 的 JS

var points = [
    {
        tag: "places",
        name: "Dubai Marina",
    }, {
        tag: "places",
        name: "Burj Khalifa",
    }, {
        tag: "Coffee",
        name: "StarBucks",
    }, {
        tag: "Coffee",
        name: "Costa",
    }, {
        tag: "Club",
        name: "Beach Club",
    }, {
        tag: "Club",
        name: "Cheers Club",
    }
];

var View = function (data) {
    this.name = ko.observable(data.name);
};

var ViewModel = function () {
    var self = this;
    this.pointsList = ko.observableArray([]);

    points.forEach(function (e) {
        self.pointsList.push(new View(e));
        console.log(e)
    });

    self.activeTag = function (a) {
        console.log(a);
    }
}
ko.applyBindings(new ViewModel());

** HTML **

<ul class="list-inline" data-bind="foreach:points">
        <li data-bind="text:tag, click: activeTag"></li>
    </ul>

    <ul data-bind="foreach:points">
        <li data-bind="text: name"></li>
    </ul>

或者有更好的解决方案吗?

2 个答案:

答案 0 :(得分:1)

所以这里有一个非常好的网站http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html,它拥有你需要的所有功能。

我使用了链接并使用了以下内容 压扁阵列(只是得到名字) 2.只获取数组中的唯一值(唯一名称) 3.对独特的名字做了一个foreach。然后点击。我更改了过滤数组的搜索条件。你可以在下面运行整个事情。只需点击运行代码段。

&#13;
&#13;
function point(tag, name) {
  var self = this;
  this.tag = ko.observable(tag);
  this.name = ko.observable(name)
}

function viewModel() {
  var self = this;
  this.points = ko.observableArray('');
  this.selectedPoint = ko.observable('');

  this.setSelected = function(item) {
    self.selectedPoint(item);
  }

  this.justtags = ko.computed(function() {
    var tags = ko.utils.arrayMap(this.points(), function(item) {
      return item.tag();
    });
    return tags.sort();
  }, this);

  this.uniquetags = ko.dependentObservable(function() {
    return ko.utils.arrayGetDistinctValues(self.justtags()).sort();
  }, this);

  this.filteredNames = ko.computed(function() {
    var filter = self.selectedPoint()
    if (!filter) {
    } else {
      return ko.utils.arrayFilter(this.points(), function(item) {
        if (item.tag() === filter) {
          return item
        };
      });
    }
  }, this);

}

var data = [{
  tag: "places",
  name: "Dubai Marina",
}, {
  tag: "places",
  name: "Burj Khalifa",
}, {
  tag: "Coffee",
  name: "StarBucks",
}, {
  tag: "Coffee",
  name: "Costa",
}, {
  tag: "Club",
  name: "Beach Club",
}, {
  tag: "Club",
  name: "Cheers Club",
}];

var vm = new viewModel();
$(document).ready(function() {
  ko.applyBindings(vm);
  $.each(data, function(i, item) {
    vm.points.push(new point(item.tag, item.name));
  })
})
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul class="list-inline" data-bind="foreach:uniquetags">
  <li data-bind="text:$data, click: $parent.setSelected"></li>
</ul>

<ul class="list-inline" data-bind="foreach:filteredNames">
  <li data-bind="text:name"></li>
</ul>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这是熟悉ko.pureComputed属性的理想问题!

您的viewmodel有两个属性:

  • Point s
  • 的数组
  • 选定的“标签”

所有其他属性可以通过组合这两个来计算。方法如下:

  • 我们创建了一个计算对象,通过标签属性对我们的点进行排序。

    { "Club": [ Point, ... ] }
    
  • 我们创建一个只接受来自此对象的选定标记的计算数组
  • 我们创建一个计算数组,该数组将对象的所有键表示可用标记

我已经移动了一些代码并选择了<select>框作为快速UI解决方案。

var Point = function (name, tag) {
  this.name = ko.observable(name);
  this.tag = ko.observable(tag);
};

Point.fromData = function(data) {
  return new Point(data.name, data.tag);
}

var ViewModel = function () {
  // This is a list of Point viewmodels, only used inside the vm
  var pointsList = ko.observableArray(
    getPoints().map(Point.fromData)
  );
  
  // This is the tag (string) that is selected, or null if there's
  // no selection
  this.activeTag = ko.observable(null);

  // This is an object that orders your points by their tag name in
  // a plain object. I.e.: { 'tagname': [Point] }
  var pointsMap = ko.pureComputed(function() {
    return pointsList().reduce(function(map, point) {
      var tag = point.tag();
      map[tag] = map[tag] || [];
      map[tag].push(point);
      return map;
    }, {});
  }, this);
  
  // All the keys in our object represent all available tags
  this.allTags = ko.pureComputed(function() {
    return Object.keys(pointsMap()).sort();
  }, this);
  
  // This is a computed list of Points. It combines the
  // selected tag and takes corresponding Point array from our map
  this.activePoints = ko.pureComputed(function() {
    var tag = this.activeTag();
    
    return tag 
      ? pointsMap()[tag]
      : pointsList();
  }, this);
  
}

ko.applyBindings(new ViewModel());

function getPoints() {
  return [{tag:"places",name:"Dubai Marina"},{tag:"places",name:"Burj Khalifa"},{tag:"Coffee",name:"StarBucks"},{tag:"Coffee",name:"Costa"},{tag:"Club",name:"Beach Club"},{tag:"Club",name:"Cheers Club"}];
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="options: allTags, value: activeTag, optionsCaption: 'no filter'"></select>
<ul data-bind="foreach: activePoints">
    <li data-bind="text: name"></li>
</ul>