使用带有敲除绑定的window.open

时间:2016-01-21 09:31:21

标签: arrays knockout.js foreach onclick

我正在使用knockout的foreach循环从数组中获取值并将其显示在href标记中。

这一切都很好但是一旦我使用javascript' s onclick(我需要这个onclick,因为我正在使用移动设备的InAppBrowser插件)并使用其中的变量,它不起作用。见这里的例子:

<div data-bind="foreach: consumerData" style="margin-bottom:100px;">  
<table>
<tr>
<td colspan="2">
<p style="font-size:larger; margin-bottom:5px;">
<a style="text-decoration:none;" 
data-bind="attr: { href: 'http://domain:8080/dsservlet/'+$data[0]+'.png?key=DK188961' }, 
text: $data[1]" target="_blank" 
onclick="window.open('http://domain:8080/dsservlet/'+$data[0]+'.png?key=DK188961', 
'_blank', 'location=yes'); return false;"></a></p>
</td></tr>
</table> 
</div>

正如您所看到的,$data[0]在data-bind属性中正常工作。但是在onclick中使用相同的$data[0]并不起作用,这仍然在foreach循环中。我假设我需要声明一个javascript变量才能使它工作,但是我如何在foreach循环中声明它?我需要在foreach循环中声明它,因为数组随着不同的值而变化。

请参阅此处的javscript部分:

var ViewModel = function() {
  this.consumerData = ko.observableArray([[174302,"BUSINESS - APPLICATION TO CONDUCT A BUSINESS FROM HOME.pdf",".pdf","DK89639"],[120183,"Glovent-Brochure.pdf",".pdf","DK472894"]]);
}

ko.applyBindings(new ViewModel());

1 个答案:

答案 0 :(得分:1)

使用Knockout,有一个different way to handle onclick: use a click binding handler。像这样:

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

    this.consumerData = ko.observableArray([[174302,"BUSINESS - APPLICATION TO CONDUCT A BUSINESS FROM HOME.pdf",".pdf","DK89639"],[120183,"Glovent-Brochure.pdf",".pdf","DK472894"]]);

    this.openServlet = function(data) {
        window.open('http://domain:8080/dsservlet/'+data[0]+'.png?key=DK188961', '_blank', 'location=yes');
    };
};

ko.applyBindings(new ViewModel());
<a data-bind="attr: { href: 'http://domain:8080/dsservlet/'+$data[0]+'.png?key=DK188961' },
              click: $parent.openServlet 
              text: $data[1]" 
   target="_blank"></a>

请仔细阅读链接文档,它将为可能出现的许多后续问题提供答案。

最后,考虑将consumerData转换为适当的子视图模型,而不是原始的数据数组。这将允许您在可观察或计算的可观察量中创建href,从而也允许您对其进行单元测试。

作为脚注,如果确实需要onclick,您可以使用attr绑定来设置它href。例如:

var ConsumerData = function(data) {
  var self = this;

  self.id = data[0];
  self.filename = data[1];
  self.extension = data[2];
  self.code = data[3];

  self.url = 'http://domain:8080/dsservlet/' + self.id + '.png?key=DK188961';

  self.openServlet = function() {
    window.open(self.url, '_blank', 'location=yes');
  };

  self.onclickValue = "window.open('http://domain:8080/dsservlet/'+data[0]+'.png?key=DK188961', '_blank', 'location=yes'); return false";

  // Overwrite them again for testing on StackOverflow (window.open is crap for testing)
  self.openServlet = function() { alert(self.url); };
  self.onclickValue = "alert('" + self.url + "'); return false;";
};

var ViewModel = function() {
  this.consumers = ko.observableArray([
    new ConsumerData([174302, "BUSINESS - APPLICATION TO CONDUCT A BUSINESS FROM HOME.pdf", ".pdf", "DK89639"]),
    new ConsumerData([120183, "Glovent-Brochure.pdf", ".pdf", "DK472894"])
  ]);
};

ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<div data-bind="foreach: consumers">
  <p>
    <a data-bind="attr: { href: url, onclick: onclickValue }, click: openServlet, text: filename" target="_blank"></a>
  </p>
</div>