Mein Problem:
Ich versuche, eine kleine Knockout JS-App in Magento 2 zu schreiben. Ich habe Probleme, die App so zu initialisieren, dass bei Verwendung ko.applyBindings(AppViewModel, document.getElementById("koTest"));
der von Magento verwendete Knockout unterbrochen wird und der folgende Fehler ausgelöst wird:
Uncaught Error: You cannot apply bindings multiple times to the same element.
Ich vermute, es liegt an:
Ich vermute , das liegt daran , dass Magento 2 bereits verwendet ko.applyBindings()
innerhalb app/code/Magento/Ui/view/base/web/js/lib/knockout/bootstrap.js
. Und da dies keinen Knoten angibt, kann ich ihn nicht mehr verwenden ko.applyBindings
.
Wenn ich ko.applyBindings(AppViewModel, document.getElementById("koTest"))
meinen Code nicht verwende, wird meine App nicht initialisiert.
Das lässt mich denken, dass ich irgendwie die ko.applyBindings()
in knockout / bootstrap.js verwenden muss, aber ich habe keine Ahnung wie, kann jemand helfen? Ich habe wenig Erfahrung mit Knockout.
Mein 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>
quelle
Antworten:
Einfache Methode, bei der Sie KEINE HTML-Vorlagen verwenden müssen
Dank Vinai Kopp habe ich endlich eine Antwort darauf erhalten. Es ist viel einfacher als meine vorherige hackige Problemumgehung (ich habe Knoten gesäubert). Sie müssen lediglich
'ko'
eine Abhängigkeit definieren und Ihren Code in eine Rückgabefunktion einfügen.Im Folgenden finden Sie ein einfaches Beispiel, in dem über JSON übergebener Text gerendert wird.
app/code/VENODR/MODULE/view/frontend/templates/knockout-example.phtml
Hier teilen wir Magento den Umfang unserer Komponenten mit (dies muss mit
data-bind: "scope: 'example-scope'"
zusätzlichen Daten übereinstimmen und diese übergeben. Dies kann die Basis-URL sein, eine einfache Nachricht, so ziemlich alles, was Sie wollen. Ich habe als Beispiel eine Zeichenfolge (PHP-Echo) übergebenUnd hier schreiben wir unser Javascript.
app/code/VENDOR/MODULE/view/frontend/web/js/knockout-example.js
Ergebnis
---------------------
Methode, bei der Sie HTML-Vorlagen verwenden müssen
Wenn Sie das HTML-Template-System in Magento2 / Knockout verwenden möchten (das Sie vermutlich für wichtige Arbeiten benötigen), müssen Sie im Vergleich zu meiner vereinfachten Antwort (unten) einige Änderungen vornehmen.
Wenn Sie die Vorlagenfunktionalität nicht benötigen, scrollen Sie nach unten zu meiner alten vereinfachten Antwort.
Die Dateien, die ich für dieses Beispiel verwende, sind:
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
Die PHTML-Vorlagendatei
Die einzige Änderung an unserer PHTML-Vorlage ist der Aufruf der
getTemplate()
Funktion:Die JS-Datei (Komponentendatei)
Es gibt einige Änderungen, die Sie an der JS-Datei vornehmen müssen. Ich werde diese unten detailliert beschreiben.
1 - Ihre Rückgabefunktion muss jetzt das uiComponent-Modul erweitern:
2 - Sie müssen eine
initialize
Funktion hinzufügen und aufrufenthis._super()
.this._super()
ruft die Funktion der übergeordneten Komponente mit demselben Namen auf. So in diesem Fall ich denke , es nennen wirdinitialize
vonuiComponent
.3 - Optional - Sie können hier auch einige Standardeinstellungen für Ihre Komponente festlegen. Ich denke, dies ist eine gute Vorgehensweise, da die Arbeit mit Ihrer Komponente einfach ist. Wenn Sie es wiederverwenden, können Sie entweder die Standardeinstellungen beibehalten oder, wenn Sie es anpassen möchten, mit neuen Argumenten aufrufen, ohne die Komponente zu ändern.
Zum Beispiel, wenn Sie auf Ausfälle im JS aussehen setzt es
exampleMessage
auf'Hello?'
noch die Seite gerendert wird , den Text alsHello Magento Stack Exchange!
. Dies liegt daran, dass ichexampleMessage
die PHTML-Datei überschrieben habe, als ich die Komponente aufgerufen habe.Die HTML-Vorlage
Ich muss mich noch umsehen und sehen, wozu die HTML-Vorlagen in der Lage sind. Ich gehe davon aus, dass die in der Knockout JS-Dokumentation erwähnten Funktionen hier verwendet werden können, um sie ziemlich flexibel zu machen.
Ich habe gerade einen Lorem-Ipsum-Text hinzugefügt. Ich werde wahrscheinlich eine weitere Frage / Antwort geben, sobald ich herausgefunden habe, was die HTML-Vorlagen können.
Das Ergebnis und das Überschreiben der Standardeinstellungen
Wie bereits erwähnt, können Sie sehen, dass ich
exampleMessage
die Vorlage überschrieben habe . Sie können sehen, dass sie beim Lesen des Textes funktioniertHello Magento Stack Exchange
.Wenn ich die Überschreibung in der Vorlagendatei entferne,
exampleMessage
wird auf die Standardeinstellung von zurückgesetztHello?
. Ich musste löschenvar/view_preprocessed
undpub/static/frontend
nachdem ich dies geändert hatte. Ich nehme an, Magento hat den Wert zwischengespeichert.quelle
https://github.com/seeni9589/Magento2/tree/master/Smart/Feedback
Benutzerdefiniertes Feedback-Formular mit dem Knockout js. Ich hoffe es hilft.
quelle