【问题标题】:using window.open with knockout binding使用带有敲除绑定的 window.open
【发布时间】:2016-04-27 11:14:39
【问题描述】:

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

这一切都很好,但是一旦我使用了 javascript 的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());

【问题讨论】:

    标签: arrays knockout.js foreach onclick


    【解决方案1】:

    在淘汰赛中,有一个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 本身转换为适当的子视图模型,而不是原始数据数组。这将允许您在 observable 或计算 observable 中创建 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>

    【讨论】:

    • 非常感谢!它几乎可以工作了。在浏览器中它可以工作,但在移动应用程序中却不行,因为 InAppBrowser 插件期望在 a 属性内有一个 onclick。有解决办法吗?
    • 如果你必须使用onclick,那么你总是可以使用attr绑定来设置它。见最后一个例子。
    猜你喜欢
    • 2013-03-24
    • 1970-01-01
    • 2014-01-03
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多