web-dev-qa-db-fra.com

Liaison par clic de tir à élimination directe sur ApplyBindings

Récemment, j'ai séparé ViewModel dans un fichier JavaScript distinct.

var Report = (function($) {
    var initialData = [];
    var viewModel = {
        reports: ko.observableArray(initialData),
        preview: function(path) {
            // preview report
        },
        otherFunctions: function() {}
    };
    return viewModel;
})(jQuery);​

Voici le code associé HTML et Knockout

<script type="text/javascript" src="path/to/report/javascript"></script>
<script type="text/javascript">
    $(document).ready(function () {
        ko.applyBindings(Report, document.body);
    });
</script>

L'interface utilisateur HTML possède un bouton sur lequel le clic est lié aux données pour la fonction d'aperçu dans le modèle de vue

<input type="button" name="Preview" id="Preview" class="btnPreview" 
    data-bind="click: Report.preview('url/to/report')" />

Problème La méthode de prévisualisation est appelée lorsque la ligne suivante s'exécute dans la fonction $ (document) .ready ()

ko.applyBindings(Report, document.body); 

C'est sans que l'utilisateur clique sur la fonction d'aperçu du bouton Aperçu. Quelle pourrait être la raison de ce comportement? Tout cela fonctionnait bien lorsque je voyais le modèle JavaScript dans la page HTML elle-même.

58
Raj

La raison en est que vous invoquez bien la fonction de prévisualisation (car écrire functionName signifie faire référence à la fonction, écrire functionName() signifie l'appeler).

Donc data-bind="click: Report.preview" fonctionnerait comme prévu, mais sans remettre le paramètre.

Comme le manuel déclare (sur un sujet différent, mais cela s'applique toujours):

Si vous avez besoin de passer plus de paramètres, une façon de le faire est d'envelopper votre gestionnaire dans un littéral de fonction qui accepte un paramètre, comme dans cet exemple:

<button data-bind="click: function(data, event) { myFunction(data, event, 'param1', 'param2') }">
    Click me
</button>

ou dans votre cas:

data-bind="click: function() { Report.preview('url/to/report') }"

Une autre solution serait de faire en sorte que preview () retourne une fonction (à peu près la même chose en fait):

preview: function(path) {
    return function() {
        // ...
    }
}
84
Niko

Une autre solution consiste à utiliser la construction 'bind':

data-bind="click: Report.preview.bind($data, 'url/to/report')" 

où le premier paramètre à bind () deviendra le 'this' dans la fonction appelée.

22
Remco Ros