Knockout.js:如何使用foreach data-bind动态分配id?

时间:2017-11-09 21:20:33

标签: javascript jquery knockout.js

我在html中有以下代码:

<ul data-bind="template: {name:'location', foreach:locations}">
 </ul>

<script type="text/html" id="location">
      <li>
        <a href='#' id="search_results" data-bind='text: title' class='w3-bar-item'></a>
      </li>
</script>

以及viewModel中的以下代码:

var locations = [ (location lists)
  ];

var viewModel = {
  title: ko.observable("Attractions in Seattle, Washington"),
  query: ko.observable(""),
};

viewModel.locations = ko.dependentObservable(function(){
    var search = this.query().toLowerCase();
          return ko.utils.arrayFilter(locations, function(location) {
            return location.title.toLowerCase().indexOf(search) >= 0;
          });
        }, viewModel);

    ko.applyBindings(viewModel);

如下图所示:

demo

并且我的常规javascript函数中有以下代码

$("#search_results").on('click', function() {
      var context = ko.contextFor(this);
      for (var i = 0; i < placeMarkers.length; i++) {
        temp = placeMarkers[i].title + ", Seattle";
        if (temp == context.$data.title) {
          getPlacesDetails(placeMarkers[i], placeInfoWindow);
        }
      }
    });

我试图根据用户点击的上下文动态显示结果,但我的功能仅适用于列表中的第一项(在这种情况下只有Space Needle)。我该如何解决?什么是knockout.js-ic方式?

+

我在viewModel中写了这样的内容:

show_infowindow: function() {
    var context = ko.contextFor(this);
    for (var i = 0; i < placeMarkers.length; i++) {
      temp = placeMarkers[i].title + ", Seattle";
      if (temp == context.$data.title) {
        getPlacesDetails(placeMarkers[i], placeInfoWindow);
      }
    }
  }

,其中

<a href='#' data-bind='text: title, click: show_infowindow' class='search_results w3-bar-item'></a>

现在没有任何工作,我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

我建议您创建viewModel函数,并在有click函数或computed属性(或new)时使用dependentObservable prior to ko 2.0运算符。这将减少调试的痛苦并理解this在回调中的含义。

因此,删除jquery click事件处理程序并将viewmodel更改为:

var viewModel = function() {
  var self = this;

  self.title = ko.observable("Attractions in Seattle, Washington");
  self.query = ko.observable("");

  self.locations = ko.computed(function(){
    var search = self.query().toLowerCase();
     return ko.utils.arrayFilter(locations, function(location) {
         return location.title.toLowerCase().indexOf(search) >= 0;
      });
   }

  self.show_infowindow = function(location){
    // "location" parameter has the current location object being clicked
    // you can use it directly instead of ko.contextFor(this);
  }
};

// don't forget the "new" keyword
ko.applyBindings(new viewModel());

更改模板以添加如下点击装订:

<script type="text/html" id="location">
      <li>
        <a href='#' id="search_results" data-bind='text: title, click:$parent.show_infowindow' class='w3-bar-item'></a>
      </li>
</script>

由于您在click内使用了foreach绑定,因此您需要在点击功能前加上$parent关键字,以获得正确的binding context。如果没有$parent,则淘汰赛会在每个show_infowindow对象中搜索location而不是viewModel

Here's another useful answer on the differences between viewModel as an object literal vs a function