Menulis Kontrol Baru

Menulis kontrol baru sering diinginkan oleh para pemrogram tingkat lanjut, karena mereka ingin menggunakan ulang kode yang mereka tulis untuk menghadapi penyajian yang komples serta interaksi pengguna.

Secara umum, ada dua cara penulisan kontrol baru: komposisi kontrol yang sudah ada dan memperluas kontrol yang sudah ada. Semuanya memerlukan kontrol baru tersebut berasal dari TControl atau kelas anaknya.

Komposisi Kontrol yang Sudah Ada

Komposisi adalah cara termudah membuat kontrol baru. Ia melibatkan terutama penurunan kontrol yang sudah ada, mengkonfigurasinya dan menjadikannya unsur komponen. Properti dari unsur komponen diperlihatkan melalui subproperti.

Seseorang dapat menciptakan sebuah kontrol baru dalam dua cara. Pertama adalah memperluas TCompositeControl dan mengganti metode TControl::createChildControls(). Kedua adalah memperluas TTemplateControl (atau kelas anaknya) dan menulis template kontrol. Yang terakhir lebih mudah digunakan dan bisa mengatur tata letak unsur komponen lebih intuitif, sementara pembentuk lebih efisien karena ia tidak perlu menguraikan template.

Sebagai contoh, kami memperlihatkan bagaimana untuk membuat kotak teks berlabel yang disebut LabeledTextBox menggunakan dua pendekatan di atas. Kotak teks berlabel menampilkan label disamping kotak teks. Kami ingin menggunakan ulang TLabel dan TTextBox yang disediakan PRADO untuk menyelesaikan tugas ini.

Komposisi dengan Menulis Template

Kita memerlukan dua file: sebuah file kelas kontrol bernama LabeledTextBox.php dan file template kontrol bernama LabeledTextBox.tpl. Keduanya harus berada di bawah direktori yang sama.

Seperti membuat halaman PRADO, kita dapat dengan mudah menuliskan konten dalam file template kontrol.

<com:TLabel ID="Label" ForControl="TextBox" /> <com:TTextBox ID="TextBox" />

Template di atas menetapkan kontrol TLabel bernama Label dan kontrol TTextBox bernama TextBox. Kita ingin memperlihatkan kedua kontrol ini. Ini bisa dikerjakan dengan mendefinisikan properti untuk masing-masing kontrol dalam file kelas LabeledTextBox. Sebagai contoh, kita dapat mendefinisikan proper Label seperti berikut,

class LabeledTextBox extends TTemplateControl { public function getLabel() { $this->ensureChildControls(); return $this->getRegisteredObject('Label'); } }

Dalam contoh di atas, metode memanggil ensureChildControls() memastikan bahwa kontrol label dan kotak teks sudah dibuat (dari template) ketika properti Label diakses. Properti TextBox dapat diimplementasikan dengan cara yang sama.

Komposisi dengan Penggantian createChildControls()

Untuk kontrol gabungan sesederhana LabeledTextBox, lebih baik membuatnya dengan memperluas TCompositeControl dan mengganti metode createChildControls(), karena ia tidak menggunakan template dan menghemat waktu penguraian template.

Kode lengkap untuk LabeledTextBox ditampilkan sebagai berikut,

class LabeledTextBox extends TCompositeControl { private $_label; private $_textbox; public function createChildControls() { $this->_label=new TLabel; $this->_label->setID('Label'); // tambah label sebagai anak dari LabeledTextBox $this->getControls()->add($this->_label); $this->_textbox=new TTextBox; $this->_textbox->setID('TextBox'); $this->_label->setForControl('TextBox'); // tambah textbox sebagai anak dari LabeledTextBox $this->getControls()->add($this->_textbox); } public function getLabel() { $this->ensureChildControls(); return $this->_label; } public function getTextBox() { $this->ensureChildControls(); return $this->_textbox; } }

Menggunakan LabeledTextBox

Untuk menggunakan kontrol LabeledTextBox, pertama kita perlu menyertakan file kelas terkait. Kemudian dalam template halaman, kita dapat menuliskan baris seperti berikut,

<com:LabeledTextBox ID="Input" Label.Text="Username" />

Dalam contoh di atas, Label.Text adalah subproperti dari LabeledTextBox, yang merujuk ke properti Text dari properti Label. Untuk lebih jelasnya atas pemakaian LabeledTextBox, lihat contoh online di atas.

Memperluas Kontrol yang Sudah Ada

Memperluas kontrol yang sudah ada sama seperti penurunan kelas konvensional. Ia membolehkan para pengembang untuk mengkustomisasi kelas kontrol yang sudah ada dengan mengganti propertinya, metodenya, event, atau membuat yang baru.

Kesulitan tugas tergantung pada seberapa banyak kelas yang sudah ada dikustomisasi. Sebagai contoh, tugas sederhana bisa mengkustomisasi kontrol TLabel, agar ia menampilkan label merah sercara standarnya. Ini akan melibatkan setelan properti ForeColor ke "red" dalam konstruktornya. Tugas yang sulit adalah membuat kontrol yang menyediakan fungsional inovatif secara lengkap. Biasanya, ini memerlukan perluasan kontrol dari kelas kontrol "tingkat rendah", seperti misalnya TControl atau TWebControl.

Dalam bagian ini, sebagian besar kami memperkenalkan basis kelas kontrol TControl dan TWebControl, memperlihatkan bagaimana mereka bisa dikustomisasi. Kami juga memperkenalkan bagaimana untuk menulis kontrol dengan fungsionalitas khusus, seperti mengambil data post, memunculkan data post dan penyatuan data dengan sumber data.

Memperluas TControl

TControl adalah basis kelas dari semua kelas kontrol. Dua metode adalah yang paling penting untuk kelas kontrol turunannya:

  • addParsedObject() - metode ini diminta oleh setiap komponen ata string teks yang dikurung di dalam tag komponen yang menetapkan kontrol dalam sebuah template. Standarnya, komponen dan string teks yang dikurung ditambahkan ke dalam koleksi Controls dari kontrol. Kontrol turunannya dapat mengganti metode ini untuk melakukan proses khusus mengenai konten yang dikurung tersebut. Sebagai contoh, TListControl hanya menerima komponen TListItem dikurung di dalam tag komponennya, dan komponen ini ditambahkan ke koleksi Items dari TListControl.
  • render() - metode ini menyajikan kontrol. Standarnya menyajikan item-item dalam koleksi Controls. Kontrol turunannya dapat mengganti metode ini guna memberikan penyajian yang dikustomisasi.
Properti dan metode penting lainnya termasuk:
  • ID - string yang secara unik mengidentifikasi kontrol diantara semua kontrol dari tempat penamaan yang sama. ID otomatis akan dibuat jika properti ID tidak disetel secara eksplisit.
  • UnqiueID - ID unik lengkap yang mengidentifikasi kontrol diantara semua kontrol pada hirarki halaman saat ini. Ia dapat digunakan untuk mencari kontrol dalam hirarki halaman dengan memanggil metode TControl::findControl(). Kontrol input pengguna sering memakainya sebagai nilai dari atribut yang sama dari elemen input HTML.
  • ClientID - mirip dengan UniqueID, kecuali bahwa ia dipakai terutama untuk penyajian dan umumnya digunakan sebagai nilai atribut id elemen HTML. Jangan bergantung pada format eksplisit ClientID.
  • Enabled - apakah kontrol ini dihidupkan atau tidak. Catatan, dalam beberapa kasus, jika salah satu kontrol leluhurnya dimatikan, kontrol juga diperlakukan sebagai dimatikan, meskipun properti Enabled adalah true.
  • Parent - kontrol leluhur dari kontrol ini. Kontrol leluhur memegang kendali apakah menyajikan kontrol ini atau tidak dan di mana menempatkan hasil yang disajikan.
  • Page - halaman yang berisi kontrol ini.
  • Controls - koleksi dari semua kontrol anak, termasuk teks statis diantaranya. Ia dapat dipakai seperti sebuah array, karena ia mengimplementasikan antarmuka Traversable. Untuk menambah anak ke kontrol, cukup sisipkan ia ke dalam koleksi Controls di posisi yang sesuai.
  • Attributes - koleksi dari atribut kustom. Ini berguna untuk membolehkan para pengguna untuk menetapkan atribut dari elemen output HTML yang tidak tercakup oleh properti kontrol.
  • getViewState() dan setViewState() - metode ini umum dipakai untuk mendefinisikan properti yang disimpan dalam kondisi tampilan.
  • saveState() dan loadState() - kedua metode ini bisa diganti untuk menyediakan langkah terakhir kondisi penyimpanan dan pengambilan.
  • Control lifecycles - Seperti halaman, kontrol juga mempunyai masa hidup. Setiap kontrol menjalani masa hidupnya dalam urutan berikut: constructor, onInit(), onLoad(), onPreRender(), render(), dan onUnload. Lebih jelasnya dapat ditemukan dalam seksi halaman.

Memperluas TWebControl

TWebControl dipakai terutama sebagai basis kelas untuk kontrol yang menyajikan elemen HTML. Ia menyediakan satu set properti yang umum diantara elemen HTML. Ia memisahkan TControl::render() ke dalam metode berikut yang lebih cocok untuk menyajikan elemen HTML:

  • addAttributesToRender() - menambah atribut untuk elemen HTML yang disajikan. Metode ini sering diganti dengan kelas tutunannya karena biasanya memiliki atribut berbeda yang disajikan.
  • renderBeginTag() - menyajikan tag HTML pembuka.
  • renderContents() - menyajikan konten dikurung di dalam elemen HTML. Standarnya menampilkan item-item dalam koleksi Controls daru kontrol. kelas turunannya dapat mengganti metode ini guna menyajikan konten yang dikustomisasi.
  • renderEndTag() - menyajikan tag HTML penutup.

Ketika menyajikan tag HTML pembuka, TWebControl memanggil getTagName() untuk mendapatkan nama tag. kelas turunannya dapat mengganti metode ini guna menyajikan nama tag yang berbeda.

Membuat Kontrol dengan Fungsional Khusus

Jika sebuah kontrol ingin merespon event sisi-klien dan menterjemahkannya ke dalam event sisi server (disebut event postback), seperti TButton, ia harus mengimplementasikan antarmuka IPostBackEventHandler.

Jika kontrol ingin bisa mengambil data post, seperti TTextBox, ia harus mengimplementasikan antarmuka IPostBackDataHandler.

Jika kontrol ingin mendapatkan data dari beberapa sumber data eksternal, ia harus memperluas TDataBoundControl. TDataBoundControl mengimplementasikan properti dasar yang diperlukan untuk mempopulasi data melalui databinding. Kenyataanya, kontrol seperti TListControl, TRepeater adalah TDataGrid semua berasal darinya.