Javascript 使用 onclick 或使用 KnockoutJS 的单击绑定传递参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10039297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:35:55  来源:igfitidea点击:

Passing parameter using onclick or a click binding with KnockoutJS

javascripthtmlknockout.jsonclick

提问by BlaShadow

I have this function:

我有这个功能:

function make(place)
{
  place.innerHTML = "somthing"
}

I used to do this with plain JavaScript and html:

我曾经用普通的 JavaScript 和 html 来做到这一点:

<button onclick="make(this.parent)">click me</button>

How can I do this using idiomatic knockout.js?

如何使用惯用的knockout.js 做到这一点?

采纳答案by John Earles

If you set up a click binding in Knockout the event is passed as the second parameter. You can use the event to obtain the element that the click occurred on and perform whatever action you want.

如果您在 Knockout 中设置点击绑定,则该事件将作为第二个参数传递。您可以使用该事件获取发生单击的元素并执行您想要的任何操作。

Here is a fiddle that demonstrates: http://jsfiddle.net/jearles/xSKyR/

这是一个演示的小提琴:http: //jsfiddle.net/jearles/xSKyR/

Alternatively, you could create your own custom binding, which will receive the element it is bound to as the first parameter. On init you could attach your own click event handler to do any actions you wish.

或者,您可以创建自己的自定义绑定,它将接收绑定到的元素作为第一个参数。在初始化时,您可以附加您自己的点击事件处理程序来执行您希望的任何操作。

http://knockoutjs.com/documentation/custom-bindings.html

http://knockoutjs.com/documentation/custom-bindings.html

HTML

HTML

<div>
    <button data-bind="click: clickMe">Click Me!</button>
</div>

Js

JS

var ViewModel = function() {
    var self = this;
    self.clickMe = function(data,event) {

      var target = event.target || event.srcElement;

      if (target.nodeType == 3) // defeat Safari bug
        target = target.parentNode;

      target.parentNode.innerHTML = "something";
    }
}

ko.applyBindings(new ViewModel());

回答by Juliano Sales

Use a binding, like in this example:

使用绑定,如本例所示:

<a href="#new-search" data-bind="click:SearchManager.bind($data,'1')">
  Search Manager
</a>
var ViewModelStructure = function () {
    var self = this;
    this.SearchManager = function (search) {
        console.log(search);
    };
}();

回答by Salvador Dali

I know this is an old question, but here is my contribution. Instead of all these tricks, you can just simply wrap a function inside another function. Like I have done here:

我知道这是一个老问题,但这是我的贡献。代替所有这些技巧,您可以简单地将一个函数包装在另一个函数中。就像我在这里所做的那样:

<div data-bind="click: function(){ f('hello parameter'); }">Click me once</div>
<div data-bind="click: function(){ f('no no parameter'); }">Click me twice</div>

var VM = function(){
   this.f = function(param){
     console.log(param);
   }
}
ko.applyBindings(new VM());

And here is the fiddle

这是小提琴

回答by Jeroen

A generic answer on how to handle clickevents with KnockoutJS...

关于如何click使用 KnockoutJS处理事件的通用答案...

Not a straight up answer to the question as asked, but probably an answer to the question most Googlers landing here have: use the clickbinding from KnockoutJSinstead of onclick. Like this:

不是对所问问题的直接回答,但可能是对大多数登陆这里的 Google 员工提出的问题的回答:使用来自 KnockoutJSclick绑定而不是onclick. 像这样:

function Item(parent, txt) {
  var self = this;
  
  self.doStuff = function(data, event) {
    console.log(data, event);
    parent.log(parent.log() + "\n  data = " + ko.toJSON(data));
  };
  
  self.doOtherStuff = function(customParam, data, event) {
    console.log(data, event);
    parent.log(parent.log() + "\n  data = " + ko.toJSON(data) + ", customParam = " + customParam);
  };
  
  self.txt = ko.observable(txt);
}

function RootVm(items) {
  var self = this;
  
  self.doParentStuff = function(data, event) {
    console.log(data, event);
    self.log(self.log() + "\n  data = " + ko.toJSON(data));
  };
  
  self.items = ko.observableArray([
    new Item(self, "John Doe"),
    new Item(self, "Marcus Aurelius")
  ]);
  self.log = ko.observable("Started logging...");
}

ko.applyBindings(new RootVm());
.parent { background: rgba(150, 150, 200, 0.5); padding: 2px; margin: 5px; }
button { margin: 2px 0; font-family: consolas; font-size: 11px; }
pre { background: #eee; border: 1px solid #ccc; padding: 5px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<div data-bind="foreach: items">
  <div class="parent">
    <span data-bind="text: txt"></span><br>
    <button data-bind="click: doStuff">click: doStuff</button><br>
    <button data-bind="click: $parent.doParentStuff">click: $parent.doParentStuff</button><br>
    <button data-bind="click: $root.doParentStuff">click: $root.doParentStuff</button><br>
    <button data-bind="click: function(data, event) { $parent.log($parent.log() + '\n  data = ' + ko.toJSON(data)); }">click: function(data, event) { $parent.log($parent.log() + '\n  data = ' + ko.toJSON(data)); }</button><br>
    <button data-bind="click: doOtherStuff.bind($data, 'test 123')">click: doOtherStuff.bind($data, 'test 123')</button><br>
    <button data-bind="click: function(data, event) { doOtherStuff('test 123', $data, event); }">click: function(data, event) { doOtherStuff($data, 'test 123', event); }</button><br>
  </div>
</div>

Click log:
<pre data-bind="text: log"></pre>



**A note about the actualquestion...*

**关于实际问题的说明...*

The actual question has one interesting bit:

实际问题有一个有趣的地方:

// Uh oh! Modifying the DOM....
place.innerHTML = "somthing"

Don't do that! Don't modify the DOM like that when using an MVVM framework like KnockoutJS, especially not the piece of the DOM that is your own parent. If you woulddo this the button would disappear (if you replace your parent's innerHTMLyou yourself will be gone forever ever!).

不要那样做!在使用像 KnockoutJS 这样的 MVVM 框架时,不要像那样修改 DOM,尤其是不要像你自己的父级那样修改 DOM。如果你这样做,按钮就会消失(如果你替换你父母的,innerHTML你自己将永远消失!)。

Instead, modify the View Modelin your handler instead, and have the View respond. For example:

相反,在您的处理程序中修改视图模型,并让视图响应。例如:

function RootVm() {
  var self = this;
  self.buttonWasClickedOnce = ko.observable(false);
  self.toggle = function(data, event) {
    self.buttonWasClickedOnce(!self.buttonWasClickedOnce());
  };
}

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

<div>
  <div  data-bind="visible: !buttonWasClickedOnce()">
    <button data-bind="click: toggle">Toggle!</button>
  </div>
  <div data-bind="visible: buttonWasClickedOnce">
    Can be made visible with toggle...
    <button data-bind="click: toggle">Untoggle!</button>
  </div>
</div>

回答by gazubi

Knockout's documentation also mentions a much cleaner way of passing extra parameters to functions bound using an on-clickbinding using function.bind like this:

Knockout 的文档还提到了一种更简洁的方法,可以将额外参数传递给on-click使用 function.bind使用绑定绑定的函数,如下所示:

<button data-bind="click: myFunction.bind($data, 'param1', 'param2')">
    Click me
</button>