Saya memiliki formulir yang menggunakan markup dari Bootstrap, seperti berikut:
<form class="form-horizontal">
<fieldset>
<legend>Legend text</legend>
<div class="control-group">
<label class="control-label" for="nameInput">Name</label>
<div class="controls">
<input type="text" class="input-xlarge" id="nameInput">
<p class="help-block">Supporting help text</p>
</div>
</div>
</fieldset>
</form>
Ada banyak kode boilerplate di sana, yang ingin saya kurangi menjadi direktif baru - form-input, seperti berikut:
<form-input label="Name" form-id="nameInput"></form-input>
menghasilkan:
<div class="control-group">
<label class="control-label" for="nameInput">Name</label>
<div class="controls">
<input type="text" class="input-xlarge" id="nameInput">
</div>
</div>
Saya memiliki banyak pekerjaan melalui template sederhana.
angular.module('formComponents', [])
.directive('formInput', function() {
return {
restrict: 'E',
scope: {
label: 'bind',
formId: 'bind'
},
template: '<div class="control-group">' +
'<label class="control-label" for="{{formId}}">{{label}}</label>' +
'<div class="controls">' +
'<input type="text" class="input-xlarge" id="{{formId}}" name="{{formId}}">' +
'</div>' +
'</div>'
}
})
Namun, ketika saya menambahkan fungsionalitas yang lebih canggih, saya terjebak.
Bagaimana saya bisa mendukung nilai default di template?
Saya ingin mengekspos parameter "type" sebagai atribut opsional pada direktif saya, misalnya:
<form-input label="Password" form-id="password" type="password"/></form-input>
<form-input label="Email address" form-id="emailAddress" type="email" /></form-input>
Namun, jika tidak ada yang ditentukan, saya ingin menggunakan default "text"
. Bagaimana saya bisa mendukung ini?
Bagaimana cara menyesuaikan template berdasarkan ada / tidak adanya atribut?
Saya juga ingin dapat mendukung atribut "diperlukan", jika ada. Misalnya:
<form-input label="Email address" form-id="emailAddress" type="email" required/></form-input>
Jika required
ada dalam direktif, saya ingin menambahkannya ke yang dihasilkan <input />
dalam output, dan mengabaikannya sebaliknya. Saya tidak yakin bagaimana mencapai ini.
Saya menduga persyaratan ini mungkin telah melampaui template sederhana, dan harus mulai menggunakan fase pra-kompilasi, tetapi saya bingung harus mulai dari mana.
sumber
type
diatur secara dinamis melalui pengikatan misalnya.type="{{ $ctrl.myForm.myField.type}}"
? Saya memeriksa semua metode di bawah ini dan tidak dapat menemukan solusi apa pun yang akan berfungsi dalam skenario ini. Sepertinya fungsi template akan melihat nilai literal dari atribut mis.tAttr['type'] == '{{ $ctrl.myForm.myField.type }}'
bukannyatAttr['type'] == 'password'
. Aku bingung.Jawaban:
sumber
htmlText
Anda menambahkanng-click
suatu tempat, akan hanya modifikasi untuk menggantielement.replaceWith(htmlText)
denganelement.replaceWith($compile(htmlText))
?htmlText
berisi arahan ng-transclude$error
tanda pada input yang dimasukkan tidak pernah disetel. Saya harus melakukan ini dalam properti link direktif:$compile(htmlText)(scope,function(_el){ element.replaceWith(_el); });
agar pengontrol formulir mengenali keberadaannya yang baru terbentuk dan memasukkannya dalam validasi. Saya tidak bisa membuatnya bekerja di properti kompilasi direktif.Mencoba menggunakan solusi yang diusulkan oleh Misko, tetapi dalam situasi saya, beberapa atribut, yang perlu digabungkan ke dalam html template saya, adalah direktif itu sendiri.
Sayangnya, tidak semua arahan yang dirujuk oleh templat yang dihasilkan berfungsi dengan benar. Saya tidak punya cukup waktu untuk menyelami kode sudut dan mencari tahu akar penyebabnya, tetapi menemukan solusi, yang berpotensi dapat membantu.
Solusinya adalah memindahkan kode, yang membuat html template, dari kompilasi ke fungsi template. Contoh berdasarkan kode dari atas:
sumber
Jawaban di atas sayangnya tidak cukup berhasil. Secara khusus, tahap kompilasi tidak memiliki akses ke cakupan, jadi Anda tidak dapat menyesuaikan kolom berdasarkan atribut dinamis. Menggunakan tahap penautan tampaknya menawarkan fleksibilitas paling besar (dalam hal membuat dom secara asinkron, dll.) Pendekatan di bawah ini membahas bahwa:
Saya telah membuat intisari dengan kode yang lebih lengkap dan penulisan pendekatannya.
sumber
Error: [ngTransclude:orphan] Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found.
Inilah yang akhirnya saya gunakan.
Saya sangat baru di AngularJS, jadi ingin melihat solusi yang lebih baik / alternatif.
Contoh penggunaan:
sumber
<form-input ng-model="appName" label="Application Name" form-id="appName" required/></form-input>
)compile
fase, yang berhubungan dengan mengubah template, danlink
fase, yang berhubungan dengan pengubahan data dalam tampilan. Sejalan dengan itu, perbedaan utama antaracompile
danlink
fungsi dalam direktif adalah bahwacompile
fungsi berurusan dengan transformasi template itu sendiri, danlink
fungsi berurusan dengan membuat hubungan dinamis antara model dan tampilan. Dalam fase kedua inilah cakupan dilampirkan kelink
fungsi yang dikompilasi , dan direktif menjadi hidup melalui pengikatan data "