Mój problem:
Próbuję napisać małą aplikację Knockout JS w Magento 2, staram się zainicjować aplikację, ponieważ gdy ko.applyBindings(AppViewModel, document.getElementById("koTest"));
ją używam , łamie Knockout używany przez Magento i generuje ten błąd:
Uncaught Error: You cannot apply bindings multiple times to the same element.
Podejrzewam, że to z powodu:
Podejrzewam, że dzieje się tak, ponieważ Magento 2 już używa ko.applyBindings()
w sobie app/code/Magento/Ui/view/base/web/js/lib/knockout/bootstrap.js
. A ponieważ nie określa to węzła, którego nie mogę użyć ko.applyBindings
ponownie.
Jeśli nie używam ko.applyBindings(AppViewModel, document.getElementById("koTest"))
w kodzie, aplikacja się nie inicjuje.
To sprawia, że myślę, że muszę jakoś użyć ko.applyBindings()
pliku knockout / bootstrap.js, ale nie mam pojęcia, jak ktoś może pomóc? Mam niewielkie doświadczenie z Knockout.
Mój kod
<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>
źródło
Odpowiedzi:
Prosta metoda, w której NIE musisz używać szablonów HTML
Dzięki Vinai Kopp w końcu mam odpowiedź na to pytanie, jest to o wiele prostsze niż moje poprzednie hacky obejście (czyściłem węzły). Wszystko, co musisz zrobić, to zdefiniować
'ko'
jako zależność i dodać kod do funkcji zwracającej.Poniżej znajduje się prosty przykład, który renderuje część tekstu przekazywanego przez JSON.
app/code/VENODR/MODULE/view/frontend/templates/knockout-example.phtml
Tutaj mówimy Magento o zakresie naszych komponentów (to musi pasować
data-bind: "scope: 'example-scope'"
i przekazywać wszelkie dodatkowe dane. Może to być podstawowy adres URL, prosta wiadomość, prawie wszystko, co chcesz. Podałem ciąg (echo PHP) jako przykładI tutaj piszemy nasz Javascript.
app/code/VENDOR/MODULE/view/frontend/web/js/knockout-example.js
Wynik
---------------------
Metoda, w której musisz użyć szablonów HTML
Jeśli chcesz korzystać z systemu szablonów HTML w Magento2 / Knockout (który, jak zakładam, będziesz potrzebować do znaczących prac), musisz wprowadzić kilka zmian w porównaniu z moją uproszczoną odpowiedzią (poniżej).
Jeśli nie potrzebujesz funkcji szablonu, przewiń w dół do mojej starej uproszczonej odpowiedzi.
Pliki, których używam w tym przykładzie to:
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
Plik szablonu PHTML
Jedyną zmianą w naszym szablonie PHTML jest wywołanie
getTemplate()
funkcji:Plik JS (komponent)
Jest kilka zmian, które musisz wprowadzić w pliku JS, opiszę je szczegółowo poniżej.
1 - Twoja funkcja powrotu musi teraz rozszerzyć moduł uiComponent:
2 - Musisz dodać
initialize
funkcję i wywołaćthis._super()
.this._super()
wywoła funkcję komponentu nadrzędnego o tej samej nazwie. Tak więc w tym przypadku mogę myśleć będzie zadzwonićinitialize
zuiComponent
.3 - Opcjonalne - Możesz również ustawić tutaj wartości domyślne dla swojego komponentu, uważam, że jest to dobra praktyka, ponieważ ułatwia on pracę z komponentem. Kiedy go użyjesz ponownie, możesz zachować wartości domyślne lub jeśli chcesz go dostosować, możesz wywołać go z nowymi argumentami bez zmiany komponentu.
Na przykład, jeśli spojrzysz na wartości domyślne w JS, ustawia to
exampleMessage
na'Hello?'
jeszcze, że strona renderuje tekst jakoHello Magento Stack Exchange!
. Jest tak, ponieważexampleMessage
nadpisałem plik PHTML, kiedy wywołałem ten komponent.Szablon HTML
Nadal muszę się rozejrzeć i zobaczyć, do czego zdolne są szablony HTML. Zakładam, że można tu użyć funkcji wymienionych w dokumentacji Knockout JS, co czyni je dość elastycznymi.
Właśnie dodałem na razie trochę tekstu lorem ipsum, zapewne udzielę innego pytania / odpowiedzi, gdy dowiem się, co mogą zrobić szablony HTML.
Wynik i zastąpienie wartości domyślnych
Jak wspomniano wcześniej, możesz zobaczyć, że nadpisałem
exampleMessage
szablon, możesz zobaczyć, jak działa tekstHello Magento Stack Exchange
.Jeśli usunę zastąpienie w pliku szablonu,
exampleMessage
nastąpi powrót do domyślnej wartościHello?
. Musiałem jednak usunąćvar/view_preprocessed
ipub/static/frontend
po zmianie. Przypuszczam, że Magento zapisał wartość w pamięci podręcznej.źródło
https://github.com/seeni9589/Magento2/tree/master/Smart/Feedback
Niestandardowy formularz opinii z nokautem js. Mam nadzieję, że to pomoże.
źródło