it-swarm.com.de

Übergabe eines Parameters mit einem Klick oder einer Klickbindung mit KnockoutJS

Ich habe diese Funktion:

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

Früher habe ich das mit einfachem JavaScript und HTML gemacht:

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

Wie kann ich das mit idiomatischen knockout.js machen?

51
BlaShadow

Wenn Sie in Knockout eine Klickbindung einrichten, wird das Ereignis als zweiter Parameter übergeben. Mit dem Ereignis können Sie das Element abrufen, auf das geklickt wurde, und die gewünschte Aktion ausführen.

Hier ist eine Geige, die zeigt: http://jsfiddle.net/jearles/xSKyR/

Alternativ können Sie eine eigene benutzerdefinierte Bindung erstellen, die das Element, an das sie gebunden ist, als ersten Parameter erhält. Bei Init können Sie Ihren eigenen Click-Event-Handler anhängen, um die gewünschten Aktionen auszuführen.

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

HTML

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

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());
31
John Earles

Verwenden Sie eine Bindung wie in diesem Beispiel:

<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);
    };
}();
80
Juliano Sales

Ich weiß, dass dies eine alte Frage ist, aber hier ist mein Beitrag. Anstelle all dieser Tricks können Sie einfach eine Funktion in eine andere Funktion einbetten. So wie ich es hier gemacht habe:

<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());

Und hier ist die Geige

26
Salvador Dali

Eine allgemeine Antwort zur Behandlung von click -Ereignissen mit KnockoutJS ...

Keine direkte Antwort auf die gestellte Frage, aber wahrscheinlich eine Antwort auf die Frage, die die meisten Googler hier gestellt haben: benutze die click Bindung von KnockoutJS anstelle von onclick . So was:

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>

** Ein Hinweis zur Aktuell Frage ... *

Die eigentliche Frage hat einen interessanten Aspekt:

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

Mach das nicht! Ändern Sie das DOM nicht auf diese Weise, wenn Sie ein MVVM-Framework wie KnockoutJS verwenden, insbesondere nicht das Teil des DOM, das Ihr eigenes übergeordnetes Element ist. Wenn Sie würde dies tun, würde der Knopf verschwinden (wenn Sie das innerHTML Ihrer Eltern ersetzen, sind Sie selbst für immer verschwunden!).

Ändern Sie stattdessen View Model in Ihrem Handler, und lassen Sie View reply. Beispielsweise:

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>
12
Jeroen

In der Dokumentation von Knockout wird auch eine viel einfachere Möglichkeit erwähnt, zusätzliche Parameter an Funktionen zu übergeben, die mit einem on-click Bindung mit function.bind wie folgt:

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