Yapısal yönergeler, bir <ng-template> öğesine uygulanan ve bu <ng-template> öğesinin içeriğini koşullu olarak veya tekrar tekrar oluşturan yönergelerdir.
Örnek kullanım durumu #
Bu kılavuzda, belirli bir veri kaynağından veri alan ve bu veri mevcut olduğunda şablonunu oluşturan yapısal bir yönerge oluşturacaksınız. Bu yönergeye SQL anahtar sözcüğü SELECT‘e atfen SelectDirective adı verilir ve bir nitelik seçici [select] ile eşleştirilir.
SelectDirective, selectFrom olarak adlandıracağınız, kullanılacak veri kaynağını adlandıran bir girdiye sahip olacaktır. Bu girdi için select öneki shorthand syntax için önemlidir. Yönerge, seçilen veriyi sağlayan bir şablon bağlamı ile <ng-template>‘ini örnekleyecektir.
Aşağıda, bu yönergenin doğrudan bir <ng-template> üzerinde kullanılmasına ilişkin bir örnek yer almaktadır:
<ng-template select let-data [selectFrom]="source">
<p>The data is: {{ data }}</p>
</ng-template>
Yapısal yönerge verinin kullanılabilir hale gelmesini bekleyebilir ve ardından <ng-template> ‘ini oluşturabilir.
YARARLI: Angular’ın <ng-template> öğesinin varsayılan olarak hiçbir şey oluşturmayan bir şablon tanımladığını unutmayın; yapısal bir yönerge uygulamadan öğeleri bir <ng-template> içine sararsanız, bu öğeler oluşturulmayacaktır.
Yapısal yönerge kısaltması #
Angular, yapısal direktifler için bir <ng-template> öğesini açıkça yazma ihtiyacını ortadan kaldıran kısa bir sözdizimini destekler.
Yapısal yönergeler, yönerge öznitelik seçicisinin önüne select gibi bir yıldız işareti (*) getirilerek doğrudan bir öğeye uygulanabilir. Angular, yapısal yönergenin önündeki yıldız işaretini, yönergeyi barındıran ve öğeyi ve alt öğelerini çevreleyen bir <ng-template>‘e dönüştürür.
Bunu SelectDirective ile aşağıdaki şekilde kullanabilirsiniz:
<p *select="let data from source">The data is: {{data}}</p>
Bu örnek, bazen mikro söz dizimi olarak da adlandırılan yapısal yönerge shorthand söz diziminin esnekliğini göstermektedir.
Bu şekilde kullanıldığında, <ng-template> etiketine sadece yapısal yönerge ve bağları uygulanır.
<p> etiketi üzerindeki diğer öznitelikler veya bağlar yalnız bırakılır. Örneğin, bu iki form eşdeğerdir:
<!-- Shorthand syntax: -->
<p class="data-view" *select="let data from source">The data is: {{data}}</p>
<!-- Long-form syntax: -->
<ng-template select let-data [selectFrom]="source">
<p class="data-view">The data is: {{data}}</p>
</ng-template>
Shorthand sözdizimi bir dizi kural aracılığıyla genişletilir. Daha kapsamlı bir grammar aşağıda tanımlanmıştır, ancak yukarıdaki örnekte bu dönüşüm aşağıdaki gibi açıklanabilir:
*select ifadesinin ilk kısmı, data şablon değişkenini bildiren let data‘dır. Ardından herhangi bir atama gelmediğinden, şablon değişken $implicit şablon bağlam özelliğine bağlanır.
İkinci sözdizimi parçası, from source şeklinde bir anahtar-ifade çiftidir. from bir bağlayıcı anahtar, source ise düzenli bir şablon ifadesidir. Bağlama anahtarları, PascalCase’e dönüştürülerek ve yapısal yönerge seçicisinin önüne eklenerek özelliklere eşlenir. from anahtarı selectFrom ile eşlenir ve bu da ifade source bağlanır. Bu nedenle, birçok yapısal yönergenin, yapısal yönergenin seçicisi ile öneklenmiş girdileri olacaktır.
Eleman başına bir yapısal yönerge #
Kısaltma sözdizimini kullanırken her öğeye yalnızca bir yapısal yönerge uygulayabilirsiniz. Bunun nedeni, bu yönergenin üzerine sarılacağı yalnızca bir <ng-template> öğesi olmasıdır. Birden fazla yönerge birden fazla iç içe <ng-template> gerektirir ve hangi yönergenin önce olması gerektiği belirsizdir. <ng-container> , aynı fiziksel DOM öğesi veya bileşeni etrafında birden fazla yapısal yönergenin uygulanması gerektiğinde sarmalayıcı katmanlar oluşturmak için kullanılabilir, bu da kullanıcının iç içe geçmiş yapıyı tanımlamasına olanak tanır.
Yapısal yönerge oluşturma #
Bu bölüm SelectDirective oluşturma konusunda size rehberlik eder.
1- Yönergeyi oluşturun #
Angular CLI’yı kullanarak aşağıdaki komutu çalıştırın; burada select yönergenin adıdır:
ng generate directive select
Angular yönerge sınıfını oluşturur ve yönergeyi bir şablonda tanımlayan CSS seçicisini [select] belirtir.
2- Yönergeyi yapısal hale getirin #
TemplateRef ve ViewContainerRef öğelerini içe aktarın. TemplateRef ve ViewContainerRef‘i özel değişkenler olarak yönerge kurucusuna ekleyin.
import {Directive, TemplateRef, ViewContainerRef} from '@angular/core';
@Directive({
standalone: true,
selector: 'select',
})
export class SelectDirective {
constructor(private templateRef: TemplateRef, private ViewContainerRef: ViewContainerRef) {}
}
3-‘selectFrom’ girişini ekleyin #
Bir selectFrom @Input() özelliği ekleyin.
export class SelectDirective {
// ...
@Input({required: true}) selectFrom!: DataSource;
}
4- İş mantığını ekleyin #
SelectDirective artık girdisiyle birlikte yapısal bir yönerge olarak iskeletlendiğinden, artık veriyi getirme ve şablonu bununla oluşturma mantığını ekleyebilirsiniz:
export class SelectDirective {
// ...
async ngOnInit() {
const data = await this.selectFrom.load();
this.viewContainerRef.createEmbeddedView(this.templateRef, {
// Create the embedded view with a context object that contains
// the data via the key `$implicit`.
$implicit: data,
});
}
}
Yapısal yönerge sözdizimi referansı #
Kendi yapısal yönergelerinizi yazarken aşağıdaki sözdizimini kullanın:
*:prefix="( :let | :expression ) (';' | ',')? ( :let | :as | :keyExp )*"
Aşağıdaki kalıplar yapısal yönerge gramerinin her bir bölümünü açıklamaktadır:
as = :export "as" :local ";"?
keyExp = :key ":"? :expression ("as" :local)? ";"?
let = "let" :local "=" :export ";"?
Anahtar Kelime | Detaylar |
prefix | HTML öznitelik anahtarı |
key | HTML öznitelik anahtarı |
local | Şablonda kullanılan yerel değişken adı |
export | Yönerge tarafından belirli bir ad altında dışa aktarılan değer |
expression | Standart Angular ifadesi |
Angular kısaltmayı nasıl çevirir? #
Angular, yapısal yönerge stenografisini aşağıdaki gibi normal bağlama sözdizimine çevirir:
Shorthand | Çeviri |
prefix and naked expression | [prefix]=”expression” |
keyExp | [prefixKey]=”expression” (Önek anahtara eklenir) |
let local | let-local=”export” |
Shorthand Örnekleri
Aşağıdaki tabloda kısa örnekler verilmiştir:
Shorthand | Angular sözdizimini nasıl yorumlar? |
*ngFor=”let item of [1,2,3]” | <ng-template ngFor let-item [ngForOf]=”[1, 2, 3]”> |
*ngFor=”let item of [1,2,3] as items; trackBy: myTrack; index as i” | <ng-template ngFor let-item [ngForOf]=”[1,2,3]” let-items=”ngForOf” [ngForTrackBy]=”myTrack” let-i=”index”> |
*ngIf=”exp” | <ng-template [ngIf]=”exp”> |
*ngIf=”exp as value” | <ng-template [ngIf]=”exp” let-value=”ngIf”> |
Özel yönergeler için şablon türü denetimini iyileştirme #
Yönerge tanımınıza şablon korumaları ekleyerek özel yönergeler için şablon türü denetimini geliştirebilirsiniz. Bu korumalar, Angular şablon türü denetleyicisinin derleme zamanında şablondaki hataları bulmasına yardımcı olur ve bu da çalışma zamanı hatalarını önleyebilir. İki farklı koruma türü mümkündür:
- ngTemplateGuard_(input), belirli bir girdinin türüne göre bir girdi ifadesinin nasıl daraltılacağını kontrol etmenizi sağlar.
- ngTemplateContextGuard, yönergenin türüne bağlı olarak şablon için bağlam nesnesinin türünü belirlemek için kullanılır.
Şablon korumaları ile tip daraltma #
Bir şablondaki yapısal yönerge, o şablonun çalışma zamanında işlenip işlenmeyeceğini kontrol eder. Bazı yapısal yönergeler, bir girdi ifadesinin türüne dayalı olarak tür daraltma gerçekleştirmek ister.
Giriş muhafazaları ile mümkün olan iki daraltma vardır:
- TypeScript tür doğrulama işlevine dayalı olarak giriş ifadesini daraltma.
- Giriş ifadesinin doğruluğuna göre daraltılması.
Bir tür doğrulama işlevi tanımlayarak giriş ifadesini daraltmak için:
// This directive only renders its template if the actor is a user.
// You want to assert that within the template, the type of the `actor`
// expression is narrowed to `User`.
@Directive(...)
class ActorIsUser {
@Input() actor: User|Robot;
static ngTemplateGuard_actor(dir: ActorIsUser, expr: User|Robot): expr is User {
// The return statement is unnecessary in practice, but included to
// prevent TypeScript errors.
return true;
}
}
Tip denetimi, şablon içinde, ngTemplateGuard_actor girdiye bağlı ifade üzerinde onaylanmış gibi davranacaktır.
Bazı yönergeler şablonlarını yalnızca bir girdi doğru olduğunda oluşturur. Doğruluğun tam semantiğini bir tür denetim işlevinde yakalamak mümkün değildir, bu nedenle bunun yerine şablon tür denetimcisine bağlayıcı ifadenin kendisinin koruma olarak kullanılması gerektiğini bildirmek için değişmez bir ‘binding’ türü kullanılabilir:
@Directive(...)
class CustomIf {
@Input() condition!: any;
static ngTemplateGuard_condition: 'binding';
}
Şablon tür denetleyicisi, koşula bağlı ifadenin şablon içinde doğru olduğu iddia edilmiş gibi davranacaktır.
Yönerge bağlamının yazılması #
Yapısal yönergeniz örneklenen şablona bir bağlam sağlıyorsa, statik bir ngTemplateContextGuard tür doğrulama işlevi sağlayarak bunu şablon içinde düzgün bir şekilde yazabilirsiniz. Bu fonksiyon, bağlamın türünü türetmek için yönergenin türünü kullanabilir; bu da yönergenin türü genel olduğunda kullanışlıdır.
Yukarıda açıklanan SelectDirective için, veri kaynağı genel olsa bile veri türünü doğru şekilde belirtmek için bir ngTemplateContextGuard uygulayabilirsiniz.
// Declare an interface for the template context:
export interface SelectTemplateContext<T> {
$implicit: T;
}
@Directive(...)
export class SelectDirective<T> {
// The directive's generic type `T` will be inferred from the `DataSource` type
// passed to the input.
@Input({required: true}) selectFrom!: DataSource<T>;
// Narrow the type of the context using the generic type of the directive.
static ngTemplateContextGuard<T>(dir: SelectDirective<T>, ctx: any): ctx is SelectTemplateContext<T> {
// As before the guard body is not used at runtime, and included only to avoid
// TypeScript errors.
return true;
}
}