2012-04-06 21 views

Respuesta

28

Si configura un enlace de clic en Knockout, el evento se pasa como el segundo parámetro. Puede usar el evento para obtener el elemento en el que se produjo el clic y realizar la acción que desee.

Aquí es un violín que demuestra: http://jsfiddle.net/jearles/xSKyR/

Como alternativa, puede crear su propia unión de encargo, que recibirá el elemento que está obligado a como el primer parámetro. En init, puede adjuntar su propio controlador de eventos click para hacer las acciones que desee.

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

Usar un enlace, como en este ejemplo:

<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); 
    }; 
}(); 
+2

versión jsFiddle : http://jsfiddle.net/fiddleSt1ck5/agjt6/ – fiat

+0

Gracias. Pero, ¿y si quiero pasar más de un parámetro? ¿Como podría hacerlo? – sudip

+1

@sudip Simple: haga clic en: PesquisaGerente.bind ($ data, '1', '2', '3') – pimbrouwers

22

Sé que esta es una vieja pregunta, pero esta es mi contribución. En lugar de todos estos trucos, simplemente puede ajustar una función dentro de otra función. Al igual que he hecho aquí:

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

Y aquí está el fiddle

+0

Me gusta más esta. Sencillo y fácil de entender. Terminó sin tener que pasar parámetros en absoluto, pero aún estaba planeando usar este método (y lo hizo para probar). – Cody

+0

Esto está bien, pero * this * para la función llamada hará referencia a la ventana en lugar de ViewModel, que normalmente se espera dentro de las funciones vinculadas de KO. function.bind ($ data) resuelve ese problema entre otros. – hemp

+1

La creación de la función dentro del cuerpo vinculante parece extraña, me gustaría ir al método bind. –

7

Una respuesta genérica sobre cómo manejar click eventos con KnockoutJS ...

No es una respuesta directa a la pregunta como se le preguntó, pero probablemente sea una respuesta a la pregunta que la mayoría de los Googlers que aterrizan aquí tienen: use the click binding from KnockoutJS en lugar de onclick. De esta manera:

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>


** Una nota acerca de la real pregunta ... *

La pregunta real tiene una parte interesante:

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

¡No hagas eso! No modifique el DOM así cuando utilice un marco MVVM como KnockoutJS, especialmente no el fragmento del DOM que es su propio elemento primario. Si fuera haga esto, el botón desaparecería (si reemplaza el innerHTML de su padre, ¡usted se habrá ido para siempre!).

lugar, modifique el Ver Modelo en el controlador en su lugar, y tienen la responden Ver . Por ejemplo:

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>

3

documentación del Knockout también menciona una manera mucho más limpia de pasar parámetros adicionales a las funciones ligadas usando un on-click unión usando function.bind así:

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