Passer le paramètre en utilisant onclick ou une liaison de clic avec KnockoutJS

j'ai cette fonction:

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

j'ai l'habitude de le faire avec du JavaScript et html:

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

Comment puis-je faire cela en utilisant knockout idiomatique.js?

46
demandé sur Jeroen 2012-04-06 08:56:31

5 réponses

si vous configurez un click binding dans Knockout l'événement est passé comme le second paramètre. Vous pouvez utiliser l'événement pour obtenir l'élément qui le clic s'est produit et réaliser toute action que vous voulez.

http://jsfiddle.net/jearles/xSKyR/

vous pouvez aussi créer votre propre reliure personnalisée, qui recevra l'élément auquel elle est liée comme premier paramètre. Sur init vous pouvez joindre votre propre clic gestionnaire d'événements pour faire toutes les actions que vous le souhaitez.

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());
29
répondu John Earles 2016-04-07 18:26:20

utilisez une reliure, comme dans cet exemple:

<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);
    };
}();
76
répondu Juliano Sales 2016-03-14 19:02:52

je sais que c'est une vieille question, mais voici ma contribution. Au lieu de tous ces trucs, vous pouvez simplement envelopper une fonction à l'intérieur d'une autre fonction. Comme je l'ai fait ici:

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

Et voici le tripoter

24
répondu Salvador Dali 2014-04-22 08:35:40

Une réponse générique sur la façon de gérer click événements avec KnockoutJS...

ce n'est Pas un droit jusqu'à la réponse à la question posée, mais probablement une réponse à la question la plupart des Googlers atterrissage ici ont: utiliser click liaison de KnockoutJS au lieu de onclick. Comme ceci:

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>

**Une remarque à propos de l' question...*

le question actuelle a un peu intéressant:

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

ne faites pas ça! Ne modifiez pas le DOM comme ça en utilisant un MVVM framework comme KnockoutJS, surtout pas le morceau du DOM qui est votre propre parent. Si vous faites ceci le bouton disparaîtrait (si vous remplacez votre parent innerHTML vous serez vous-même parti pour toujours!).

au lieu de cela, modifiez le Modèle De Vue dans votre gestionnaire à la place, et avoir la vue répondre. Par exemple:

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>
8
répondu Jeroen 2016-03-14 19:35:21

la documentation de Knockout mentionne aussi une façon beaucoup plus propre de passer des paramètres supplémentaires aux fonctions liées en utilisant un on-click liaison par fonction.lier comme ceci:

<button data-bind="click: myFunction.bind($data, 'param1', 'param2')">
    Click me
</button>
3
répondu gazubi 2016-05-16 06:49:38