Mon problème:
J'essaie d'écrire une petite application Knockout JS dans Magento 2, j'ai du mal à initialiser l'application car lorsque je l'utilise, ko.applyBindings(AppViewModel, document.getElementById("koTest"));
cela brise le Knockout utilisé par Magento et génère cette erreur:
Uncaught Error: You cannot apply bindings multiple times to the same element.
Je soupçonne que c'est à cause de:
Je soupçonne que c'est parce que Magento 2 utilise déjà à l' ko.applyBindings()
intérieur app/code/Magento/Ui/view/base/web/js/lib/knockout/bootstrap.js
. Et comme cela ne spécifie pas un nœud que je ne peux plus utiliser ko.applyBindings
.
Si je n'utilise pas ko.applyBindings(AppViewModel, document.getElementById("koTest"))
dans mon code, mon application ne s'initialise pas.
Cela me fait penser que je dois en quelque sorte utiliser le ko.applyBindings()
fichier in knockout / bootstrap.js mais je ne sais pas comment, quelqu'un peut-il aider? J'ai peu d'expérience avec Knockout.
Mon code
<script type="text/javascript">
require([
'ko'
], function(ko) {
// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
this.capitalizeLastName = function() {
var currentVal = this.lastName();
this.lastName(currentVal.toUpperCase());
};
}
ko.applyBindings(AppViewModel, document.getElementById("koTest"));
});
</script>
<!-- This is a *view* - HTML markup that defines the appearance of your UI -->
<div id="koTest">
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>Full name: <strong data-bind="text: fullName"></strong></p>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
<p>Full name: <input data-bind="value: fullName" /></p>
<button data-bind="click: capitalizeLastName">Capitalise</button>
</div>
la source
Réponses:
Méthode simple où vous n'avez PAS besoin d'utiliser des modèles html
Grâce à Vinai Kopp, j'ai enfin une réponse à cela, c'est beaucoup plus simple que ma solution de contournement précédente (je nettoyais les nœuds). Il vous suffit de définir
'ko'
comme une dépendance et d'ajouter votre code dans une fonction de retour.Vous trouverez ci-dessous un exemple simple qui restitue du texte transmis via JSON.
app/code/VENODR/MODULE/view/frontend/templates/knockout-example.phtml
Ici, nous indiquons à Magento la portée de nos composants (cela doit correspondre
data-bind: "scope: 'example-scope'"
et transmettre toutes les données supplémentaires. Cela pourrait être l'URL de base, un message simple, à peu près tout ce que vous voulez. J'ai passé une chaîne (écho PHP) comme exempleEt ici, nous écrivons notre Javascript.
app/code/VENDOR/MODULE/view/frontend/web/js/knockout-example.js
Résultat
---------------------
Méthode où vous avez besoin d'utiliser des modèles HTML
Si vous souhaitez utiliser le système de création de modèles HTML dans Magento2 / Knockout (dont je suppose que vous aurez besoin pour tout travail important), vous devrez apporter quelques modifications par rapport à ma réponse simplifiée (ci-dessous).
Si vous n'avez pas besoin de la fonctionnalité de modèle, faites défiler vers le bas jusqu'à mon ancienne réponse simplifiée.
Les fichiers que j'utilise pour cet exemple sont:
app/design/frontend/VENDOR/THEME/Magento_Cms/templates/knockout.phtml
app/design/frontend/VENDOR/THEME/Magento_Cms/web/js/knockout-example.js
app/design/frontend/VENDOR/THEME/Magento_Cms/web/template/test.html
Le fichier modèle PHTML
Le seul changement à notre modèle PHTML est l'appel à la
getTemplate()
fonction:Le fichier JS (composant)
Il y a quelques changements que vous devrez apporter au fichier JS, je vais les détailler ci-dessous.
1 - Votre fonction de retour doit maintenant étendre le module uiComponent:
2 - Vous devez ajouter une
initialize
fonction et appelerthis._super()
.this._super()
appellera la fonction du composant parent avec le même nom. Donc , dans ce cas , je pense qu'il appellerainitialize
deuiComponent
.3 - Facultatif - Vous pouvez également définir des valeurs par défaut pour votre composant ici, je pense que c'est une bonne pratique à suivre car cela rend votre composant facile à utiliser. Lorsque vous le réutilisez, vous pouvez conserver les valeurs par défaut ou si vous souhaitez le personnaliser, vous pouvez l'appeler avec de nouveaux arguments sans modifier le composant.
Par exemple, si vous regardez les valeurs par défaut dans la JS il met
exampleMessage
à'Hello?'
encore la page est rendu le texteHello Magento Stack Exchange!
. En effet, j'ai remplacéexampleMessage
le fichier PHTML lorsque j'ai appelé le composant.Le modèle HTML
Je dois encore creuser et voir de quoi les modèles HTML sont capables, je suppose que les fonctionnalités mentionnées dans la documentation Knockout JS peuvent être utilisées ici pour les rendre assez flexibles.
Je viens d'ajouter du texte lorem ipsum pour le moment, je fournirai probablement une autre question / réponse une fois que j'aurai compris ce que les modèles HTML peuvent faire.
Le résultat et le remplacement des valeurs par défaut
Comme mentionné précédemment, vous pouvez voir que j'ai remplacé
exampleMessage
le modèle, vous pouvez le voir fonctionner pendant la lecture du texteHello Magento Stack Exchange
.Si je supprime le remplacement dans le fichier modèle,
exampleMessage
il reviendra à sa valeur par défautHello?
. J'ai dû supprimervar/view_preprocessed
etpub/static/frontend
après avoir changé cela cependant. Je suppose que Magento a mis en cache la valeur.la source
https://github.com/seeni9589/Magento2/tree/master/Smart/Feedback
Formulaire de rétroaction personnalisé avec les knockout js. J'espère que cela aide.
la source