Saya sedang mengusahakan rantaian warisan 3 kelas boleh dilanjutkan.
Renderer (asas) -> Peti Mel (kanak-kanak) -> Peti SuratMasuk (anak akhir)
Mereka masing-masing mempunyai kelas render
方法。孩子只是重写渲染器(基础)render
方法最后他们无论如何应该使用渲染器的render
kaedah(Asas< /strong>) mereka sendiri. Masalah saya ialah apabila saya melaksanakan kaedah tertentu dalam kelas Renderer (createElementWithTextInside), ia tidak betul-betul melaksanakan kaedah Renderer's render (Renderer .render()), tetapi ia melakukannya dari kelas extensible Starts di hujung rantai. Contohnya, ia mula melintasi:
1 - MailboxInbox.render
2 - Mailbox.render
3 - Renderer.render
Saya faham cara kelas/warisan js berfungsi di sebalik tabir. Javascript hanya memanjangkan prototaip objek dan skrip akan berulang ke atasnya dsb. Tetapi soalan saya ialah: Bagaimanakah saya boleh mengelakkan tingkah laku ini dan terus memanggil kaedah Renderer.render dalam kaedahnya apabila diperlukan?
Saya tidak dapat menyimpan __diri dalam penyebar kerana ia akan menunjuk ke this
contoh semasa (MailboxInbox) pula. Juga, saya tidak boleh menggunakan .bind/lambda (fungsi anak panah) kerana saya perlu menyimpan konteks
Violin
class Renderer { get noResultContent() { const p = this.createElement('p', 'no-result-msg'); const textNode = document.createTextNode('No result'); p.appendChild(textNode); return p; }; createElement(tag, className) { if (!tag) throw new Error('Tag must be passed!'); const res = document.createElement(tag); res.classList.add(className); return res; } createTextNode(text) { const res = document.createTextNode(text); return res; } /** * automatically creates an el based on tag, text node and insert the text node into the el */ createElementWithTextInside(tag, className, content) { const el = this.createElement(tag, className); const text = this.createTextNode(content); this.render(el, text); return el; } checkIfDomEl = el => el instanceof Element; render(el, content) { console.log('3: RENDERER RENDER') if (!this.checkIfDomEl(el)) throw new Error(`Please, pass the valid DOM el. Received: ${el}, ${typeof el} `); const finalContent = content || this.noResultContent; el.appendChild(finalContent); } } -------- class Mailbox extends Renderer { rootEl; constructor(selector) { super(); this.rootEl = document.querySelector(selector); } renderTitle(content) { if (!content) return null; const titleEl = super.createElementWithTextInside('h3', 'mailbox-title', content) super.render(this.rootEl, titleEl); } render() { console.log('2: MAILBOX RENDER') super.render(this.rootEl); } } -------- class MailboxInbox extends Mailbox { title = "Inbox" constructor(params) { const { selector } = params; super(selector); } renderTitle() { super.renderTitle(this.title); } render() { console.log('1: INBOX RENDER') super.render(); } } -------- const inbox = new MailboxInbox({selector: '#container'}); inbox.renderTitle()
Di sini ia hanya dipaparkan dalam konsol:
1: Penyampaian peti masuk
2: Penyampaian peti mel
3: Penyampaian pemaparan
Terima kasih atas bantuan anda! salam hormat!
Dikemas kini
Pada asasnya saya hanya mahu mempunyai kelas render
asas yang boleh menerima parameter: (el,content)
(kandungan adalah pilihan) dan render
类,它可以接受参数:(el,content)
(内容是可选的)和Children我想用一些预定义的 el
和 content
等在他们自己的 .render()
方法中覆盖它,但是如果我尝试执行 renderer.render()
方法来自 Renderer 内部,它遍历整个链,我的参数丢失了,因为在 MailboxInbox 中,渲染方法当前没有'不接受任何参数,所以我要么应该让它接受参数并将它们传递到整个链,要么只是在 Renderer 中定义一些专用类,如 baseRender
Kanak-kanak< /p>Saya mahu menggunakan Beberapa pratakrif < code>el dan content
dsb. mengatasinya dalam kaedah .render()
mereka sendiri, tetapi jika saya cuba melaksanakan renderer.render()
kaedah datang dari dalam 🎜Renderer🎜 dan ia melalui keseluruhan rantaian dan parameter saya hilang kerana dalam 🎜MailboxInbox🎜 kaedah render pada masa ini tidak menerima sebarang parameter, jadi saya harus sama ada membuatnya Terima parameter dan luluskannya sepanjang rantaian, atau tentukan beberapa kelas khusus seperti baseRender
dalam 🎜Renderer🎜 dan panggil terus 🎜
Secara teknikal anda boleh menggantikan
this.render(el, text);
denganIa memintas carian harta warisan. Walau bagaimanapun, ini secara amnya bukan amalan yang baik dan akan kehilangan kelebihan harta pusaka.
Nasib baik, anda telah mengenal pasti masalah sebenar dengan kemas kini anda:class
Prinsip Penggantian Lebih Kaya.
Anda juga telah mengenal pasti penyelesaian yang berpotensi:sebaliknya).
render
和baseRender
,而是推荐类似renderContent(el, content)
和renderDefault (el)
,它们的签名实际上不同 - 并且都可以被覆盖。然而,看看使用两个参数调用时render
的实现,在我看来,除了调用el.appendChild(content)
之外,它实际上没有做任何有用的事情,所以我'宁愿完全放弃它并只调用appendChild
(除非您需要覆盖具体行为的能力,例如通过执行el.prepend(content)