Masalahku:
Saya mencoba untuk menulis aplikasi Knockout JS kecil di dalam Magento 2, saya berjuang untuk menginisialisasi aplikasi seperti ketika saya menggunakannya ko.applyBindings(AppViewModel, document.getElementById("koTest"));
merusak Knockout yang digunakan oleh Magento dan melempar kesalahan ini:
Uncaught Error: You cannot apply bindings multiple times to the same element.
Saya menduga itu karena:
Saya menduga ini karena Magento 2 sudah digunakan di ko.applyBindings()
dalam app/code/Magento/Ui/view/base/web/js/lib/knockout/bootstrap.js
. Dan karena itu tidak menentukan node saya tidak bisa menggunakan ko.applyBindings
lagi.
Jika saya tidak menggunakan ko.applyBindings(AppViewModel, document.getElementById("koTest"))
kode saya maka aplikasi saya tidak diinisialisasi.
Ini membuat saya berpikir saya perlu entah bagaimana menggunakan ko.applyBindings()
di knockout / bootstrap.js tapi saya tidak tahu caranya, ada yang bisa membantu? Saya memiliki sedikit pengalaman dengan Knockout.
Kode Saya
<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>
sumber
Jawaban:
Metode sederhana di mana Anda TIDAK perlu menggunakan templat html
Berkat Vinai Kopp, saya akhirnya mendapat jawaban untuk ini, itu jauh lebih sederhana daripada solusi hacky saya sebelumnya (saya sedang membersihkan node). Yang perlu Anda lakukan adalah mendefinisikan
'ko'
sebagai ketergantungan dan menambahkan kode Anda di dalam fungsi kembali.Di bawah ini adalah contoh sederhana yang menerjemahkan beberapa teks yang dikirimkan melalui JSON.
app/code/VENODR/MODULE/view/frontend/templates/knockout-example.phtml
Di sini kami memberi tahu Magento ruang lingkup komponen kami (ini harus cocok
data-bind: "scope: 'example-scope'"
dan meneruskan data tambahan apa pun. Ini bisa menjadi basis URL, pesan sederhana, cukup banyak apa pun yang Anda inginkan. Saya telah mengirimkan string (PHP echo) sebagai contohDan di sini kita menulis Javascript kita.
app/code/VENDOR/MODULE/view/frontend/web/js/knockout-example.js
Hasil
---------------------
Metode di mana Anda DO perlu menggunakan templat HTML
Jika Anda ingin menggunakan sistem templating HTML dalam Magento2 / Knockout (yang saya duga Anda perlukan untuk pekerjaan yang signifikan) ada beberapa perubahan yang perlu Anda lakukan dibandingkan dengan jawaban saya yang disederhanakan (di bawah).
Jika Anda tidak memerlukan fungsionalitas templat, gulir ke bawah ke jawaban sederhana saya yang lama.
File yang saya gunakan untuk contoh ini adalah:
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
File template PHTML
Satu-satunya perubahan pada templat PHTML kami adalah panggilan ke
getTemplate()
fungsi:File JS (komponen)
Ada beberapa perubahan yang perlu Anda lakukan pada file JS, saya akan menjelaskannya di bawah ini.
1 - Fungsi pengembalian Anda sekarang perlu memperluas modul uiComponent:
2 - Anda perlu menambahkan
initialize
fungsi dan panggilanthis._super()
.this._super()
akan memanggil fungsi komponen induk dengan nama yang sama. Jadi dalam hal ini saya pikir itu akan memanggilinitialize
dariuiComponent
.3 - Opsional - Anda juga dapat menetapkan beberapa default untuk komponen Anda di sini, saya pikir ini adalah praktik yang baik untuk diikuti karena membuat komponen Anda mudah untuk dikerjakan. Ketika Anda menggunakannya kembali, Anda dapat menyimpan default atau jika Anda ingin menyesuaikannya Anda bisa menyebutnya dengan argumen baru tanpa mengubah komponen.
Misalnya, jika Anda melihat default di JS yang ditetapkan
exampleMessage
untuk'Hello?'
halaman belum rendering teks sebagaiHello Magento Stack Exchange!
. Ini karena saya telah ditimpaexampleMessage
dalam file PHTML ketika saya memanggil komponen.Template HTML
Saya masih mencari-cari dan melihat apa yang bisa templat HTML, saya kira fitur yang disebutkan pada dokumentasi Knockout JS dapat digunakan di sini membuat mereka cukup fleksibel.
Saya baru saja menambahkan beberapa teks lorem ipsum untuk saat ini, saya kemungkinan akan memberikan pertanyaan / jawaban lain setelah saya mengetahui apa yang dapat dilakukan templat HTML.
Hasilnya, dan menimpa default
Seperti disebutkan sebelumnya Anda dapat melihat bahwa saya telah ditimpa
exampleMessage
dalam template, Anda dapat melihatnya berfungsi saat teks dibacaHello Magento Stack Exchange
.Jika saya menghapus override dalam file template
exampleMessage
akan kembali ke defaultnyaHello?
. Saya memang perlu menghapusvar/view_preprocessed
danpub/static/frontend
setelah mengubah ini. Saya kira Magento telah menyimpan nilai.sumber
https://github.com/seeni9589/Magento2/tree/master/Smart/Feedback
Formulir Umpan Balik Kustom dengan js KO. Semoga ini bisa membantu.
sumber