Jestem zainteresowany, aby dowiedzieć się, jaki jest wymóg / przypadek użycia, aby chcieć zmienić nazwę parametru wiązania, takiego jak ten przykład?
LDJ
31
Ma to na celu uniknięcie powtarzania czegoś takiego jak tab [element] .val według instancji. Wiem, że mogę rozwiązać problem w komponencie, ale właśnie zastanawiałem się, jak to zrobić w szablonie (nawet jeśli nie mogę tego rozwiązać).
Scipion
2
@LDJ jeden przykładowy przypadek użycia: wydajność. Użyj próbki stackblitz.com/angular/… <mat-checkbox [zaznaczone] = "descendantsAllSelected (node)" [indeterminate] = "descendantsPartIALSelected (node)" (change) = "todoItemSelectionToggle (node)"> {{node. item}} </mat-checkbox> w rzeczywistości descendantsPartIALSelected () wywołuje descendantsAllSelected (). Oznacza to, że kiedyś potomkowie AllSelected są wywoływani dwukrotnie. Jeśli istnieje zmienna lokalna, można tego uniknąć.
Steven.Xi
3
<div *ngIf="{name:'john'} as user1; let user"> <i>{{user1|json}}</i> <i>{{user|json}}</i> </div>
dasfdsa
@dasfdsa Wierzę user1 === user, więc albo to robisz, *ngIf="{name:'john'} as user1albo *ngIf="{name:'john'};let userjak w odpowiedzi yurzui .
CPHPython
Odpowiedzi:
174
Aktualizacja
Możemy po prostu stworzyć taką dyrektywę *ngIfi ją nazwać*ngVar
to zadziała w większości przypadków, ale nie jest to ogólne rozwiązanie, ponieważ polega na variablebyciu prawdomównym
Keith
6
@ Keith Dzięki za zwrócenie na to uwagi. Możesz
rzucić
3
To powinna być nowa odpowiedź, ponieważ 1) jest nowocześniejsza niż inne rozwiązanie 2) podsumowuje żądania ściągania powiązane z bieżącą odpowiedzią i oszczędza dużo czasu 3) zawiera przykłady zamiast wbudowanego łącza zewnętrznego. Dzięki za pokazanie tego. AFAIK jakikolwiek zawinięty obiekt {}oceni prawdę, więc to rozwiązanie jest dość solidne.
kvanberendonck
4
Na przykład przyciski rozwijane: *ngIf="{ expanded: false } as scope"a jeśli używasz bootstrap, możesz po prostu użyć [ngClass]="{ 'in': scope.expanded }"i (click)="scope.expanded = !scope.expanded"zamiast dodawać cokolwiek do js/ tsplików.
To właśnie wymyśliłem instynktownie - z tym też działa *ngFor="let a of [(someStream$ | async).someA]. Wydaje mi się, że użyty z <ng-container>to całkiem dobrze działa!
Angelos Pikoulas
2
W takim przypadku *ngFornależy pamiętać, że cała zagnieżdżona zawartość zostanie odtworzona, jeśli zmieni się wartość zmiennej, dopóki nie zostanie określona trackByfunkcja, która zwraca ten sam identyfikator dla wszystkich wartości.
Valeriy Katkov
74
Możesz zadeklarować zmienne w kodzie HTML, używając templateelementu w Angular 2 lub ng-templateAngular 4+.
Szablony mają obiekt kontekstowy, którego właściwości można przypisać do zmiennych za pomocą letskładni wiązania. Pamiętaj, że musisz określić wylot dla szablonu, ale może to być odniesienie do samego siebie.
Aby działało, musiałem zmienić kod z „<szablon ...” na „<ng-szablon ...”.
Humppakäräjät
2
Tak, można używać tylko <template>w kątowej 2. Można użyć jednej <template>lub <ng-template>w kątowym 4, ale należy używać tylko <ng-template>. Angular 5 porzucił wsparcie dla <template>.
Steven Liekens
Do czego służy t?
matttm
1
@matttm #tto zmienna szablonu, która przechowuje ng-template. Służy [ngTemplateOutlet]="t"do tworzenia odniesienia do samego szablonu ng.
Steven Liekens
To dziwne, ale działa! Angular powinien to uprościć dzięki wbudowanej zmiennej dyrektywie. Dzięki.
Istnieją zmienne szablonów, ale przypisywanie dowolnych wartości nie jest obsługiwane. Można ich używać tylko w odniesieniu do elementów, do których są stosowane, eksportowanych nazw dyrektyw lub komponentów i zmiennych zakresu dla dyrektyw strukturalnych, takich jak ngFor,
Czy nie byłoby możliwe stworzenie w tym celu dyrektywy strukturalnej?
Scipion
Jeśli potrzebujesz tego wielokrotnie, dyrektywa może zrobić to, co chcesz. Dyrektywa strukturalna tworzy własny pogląd, prawdopodobnie nie tego chcesz.
Günter Zöchbauer
1
@ GünterZöchbauer, bardzo dobre rzeczy. Wiem, że prawdopodobnie lepszą praktyką jest obliczanie / przygotowywanie zmiennych w component.tspliku. Ale o wiele łatwiej jest mi je wyświetlić w niektórych przypadkach ze względu na schemat synchronizacji, który wdrażam w całej mojej aplikacji. Korzystam z reguł odwołań javascript, gdy różne zmienne wskazują ten sam obiekt.
AmmarCSE,
Otrzymuję błąd jak There is no directive with "exportAs" set to "var". Czy ktoś może mi powiedzieć, jaki popełniłem błąd? Użyłem powyższej dyrektywy.
Partha Sarathi Ghosh
Być może nie dodać do dyrektywy declarations: [...]o @NgModule(). Jeśli to nie jest problem, utwórz nowe pytanie i podaj kod umożliwiający zdiagnozowanie problemu.
Nie przekazuje kompilacji „produkcyjnej” w takiej postaci, w jakiej jest (pokazuje również jako błędy według IDE). Dodaj [key: string]: any;do, Classaby obejść ten problem.
Charly,
7
W przypadku, gdy chcesz uzyskać odpowiedź funkcji i ustawić ją w zmiennej, możesz użyć jej w szablonie w następujący sposób, ng-containeraby uniknąć modyfikacji szablonu.
<ng-container *ngIf="methodName(parameters) as respObject">
{{respObject.name}}
</ng-container>
Metoda w komponencie może być podobna
methodName(parameters: any): any {return{name:'Test name'};}
Używam kątowego 6x i skończyło się na tym, że użyłem poniżej fragmentu kodu. Mam scenerię, w której muszę znaleźć użytkownika z obiektu zadania. zawiera tablicę użytkowników, ale muszę wybrać przypisanego użytkownika.
@Amirreza, a ściślej używam ElementRef do tymczasowego przechowywania wartości.
Jack Rus
Niesamowite! Musiałem użyć, "?"ponieważ miałem komunikat „Wartość identyfikatora” nie jest zdefiniowana ”jak to =>„ open? .Value ”Ale to działa !!
A. Morel,
1
Podobało mi się podejście polegające na stworzeniu w tym celu dyrektywy (dobre połączenie @yurzui).
Skończyło się na tym, że znalazłem dyrektywę Angular „let” w artykule Medium, która ładnie wyjaśnia ten problem i proponuje niestandardową dyrektywę let, która ostatecznie świetnie działa w moim przypadku użycia z minimalnymi zmianami kodu.
Oto sedno (w momencie publikowania) moich modyfikacji:
Dla tych, którzy zdecydowali się zastosować dyrektywę strukturalną jako zamiennik *ngIf, należy pamiętać, że kontekst dyrektywy nie jest domyślnie sprawdzany pod względem typu. Aby utworzyć bezpieczną dyrektywę typu ngTemplateContextGuardnależy dodać właściwość, patrz Pisanie kontekstu dyrektywy . Na przykład:
import{Directive,Input,TemplateRef,ViewContainerRef}from'@angular/core';@Directive({// don't use 'ng' prefix since it's reserved for Angular
selector:'[appVar]',})exportclassVarDirective<T = unknown>{// https://angular.io/guide/structural-directives#typing-the-directives-contextstatic ngTemplateContextGuard<T>(dir:VarDirective<T>, ctx: any): ctx is Context<T>{returntrue;}private context?:Context<T>;constructor(private vcRef:ViewContainerRef,private templateRef:TemplateRef<Context<T>>){}@Input()set appVar(value: T){if(this.context){this.context.appVar = value;}else{this.context ={ appVar: value };this.vcRef.createEmbeddedView(this.templateRef,this.context);}}}interfaceContext<T>{
appVar: T;}
Dyrektywa może być używana tak samo *ngIf, z tym wyjątkiem, że może przechowywać fałszywe wartości:
<ng-container *appVar="false as value">{{value}}</ng-container><!-- error: User doesn't have `nam` property--><ng-container *appVar="user as user">{{user.nam}}</ng-container><ng-container *appVar="user$ | async as user">{{user.name}}</ng-container>
Jedyną wadą w porównaniu z *ngIftym jest to, że Angular Language Service nie jest w stanie ustalić typu zmiennej, więc nie ma uzupełniania kodu w szablonach. Mam nadzieję, że zostanie to wkrótce naprawione.
<div *ngIf="{name:'john'} as user1; let user"> <i>{{user1|json}}</i> <i>{{user|json}}</i> </div>
user1 === user
, więc albo to robisz,*ngIf="{name:'john'} as user1
albo*ngIf="{name:'john'};let user
jak w odpowiedzi yurzui .Odpowiedzi:
Aktualizacja
Możemy po prostu stworzyć taką dyrektywę
*ngIf
i ją nazwać*ngVar
ng-var.directive.ts
dzięki tej
*ngVar
dyrektywie możemy zastosować następującelub
lub
lub
Przykład plunkera Angular4 ngVar
Zobacz też
Oryginalna odpowiedź
Angular v4
1)
div
+ngIf
+let
2)
div
+ngIf
+as
widok
component.ts
3) Jeśli nie chcesz tworzyć opakowania,
div
którego możesz użyćng-container
widok
Jak wspomniano w komentarzach @Keith
Zobacz aktualizację dla innego podejścia.
źródło
variable
byciu prawdomównym{}
oceni prawdę, więc to rozwiązanie jest dość solidne.*ngIf="{ expanded: false } as scope"
a jeśli używasz bootstrap, możesz po prostu użyć[ngClass]="{ 'in': scope.expanded }"
i(click)="scope.expanded = !scope.expanded"
zamiast dodawać cokolwiek dojs
/ts
plików.*ngIf
z githubem (zwraca uwagę na proste, a nie niestandardowe rzeczy związane z Ngvar): github.com/angular/angular/angular/issues/14985Brzydkie, ale:
W połączeniu z potokiem asynchronicznym:
źródło
*ngFor="let a of [(someStream$ | async).someA]
. Wydaje mi się, że użyty z<ng-container>
to całkiem dobrze działa!*ngFor
należy pamiętać, że cała zagnieżdżona zawartość zostanie odtworzona, jeśli zmieni się wartość zmiennej, dopóki nie zostanie określonatrackBy
funkcja, która zwraca ten sam identyfikator dla wszystkich wartości.Możesz zadeklarować zmienne w kodzie HTML, używając
template
elementu w Angular 2 lubng-template
Angular 4+.Szablony mają obiekt kontekstowy, którego właściwości można przypisać do zmiennych za pomocą
let
składni wiązania. Pamiętaj, że musisz określić wylot dla szablonu, ale może to być odniesienie do samego siebie.Można zmniejszyć ilość kodu, używając
$implicit
właściwości obiektu kontekstu zamiast właściwości niestandardowej.Obiekt kontekstu może być obiektem dosłownym lub dowolnym innym wyrażeniem wiążącym. Wydaje się, że nawet rury działają w nawiasach.
Prawidłowe przykłady
ngTemplateOutletContext
:[ngTemplateOutletContext]="{ aVariable: 123 }"
[ngTemplateOutletContext]="{ aVariable: (3.141592 | number:'3.1-5') }"
[ngTemplateOutletContext]="{ aVariable: anotherVariable }"
używać zlet-a="aVariable"
[ngTemplateOutletContext]="{ $implicit: anotherVariable }"
używać zlet-a
[ngTemplateOutletContext]="ctx"
gdziectx
jest własność publicznaźródło
<template>
w kątowej 2. Można użyć jednej<template>
lub<ng-template>
w kątowym 4, ale należy używać tylko<ng-template>
. Angular 5 porzucił wsparcie dla<template>
.t
?#t
to zmienna szablonu, która przechowujeng-template
. Służy[ngTemplateOutlet]="t"
do tworzenia odniesienia do samego szablonu ng.aktualizacja 3
Problem 2451 został naprawiony w Angular 4.0.0
Zobacz też
aktualizacja 2
To nie jest obsługiwane.
Istnieją zmienne szablonów, ale przypisywanie dowolnych wartości nie jest obsługiwane. Można ich używać tylko w odniesieniu do elementów, do których są stosowane, eksportowanych nazw dyrektyw lub komponentów i zmiennych zakresu dla dyrektyw strukturalnych, takich jak
ngFor
,Zobacz także https://github.com/angular/angular/issues/2451
Aktualizacja 1
i zainicjuj to jak
lub
i użyj zmiennej like
(nie testowany)
#aVariable
tworzy odniesienie doVarDirective
(exportAs: 'var'
)var="abc"
tworzy instancjęVarDirective
i przekazuje wartość ciągu"abc"
do wartości wejściowej.aVariable.var
odczytuje wartość przypisaną do danych wejściowychvar
dyrektywvar
źródło
component.ts
pliku. Ale o wiele łatwiej jest mi je wyświetlić w niektórych przypadkach ze względu na schemat synchronizacji, który wdrażam w całej mojej aplikacji. Korzystam z reguł odwołań javascript, gdy różne zmienne wskazują ten sam obiekt.There is no directive with "exportAs" set to "var"
. Czy ktoś może mi powiedzieć, jaki popełniłem błąd? Użyłem powyższej dyrektywy.declarations: [...]
o@NgModule()
. Jeśli to nie jest problem, utwórz nowe pytanie i podaj kod umożliwiający zdiagnozowanie problemu.Sugerowałbym to: https://medium.com/@AustinMatherne/angular-let-directive-a168d4248138
Ta dyrektywa pozwala napisać coś takiego:
źródło
Oto dyrektywa, którą napisałem, która rozszerza zastosowanie parametru dekoratora exportAs i pozwala na użycie słownika jako zmiennej lokalnej.
Możesz użyć go w szablonie w następujący sposób:
Oczywiście #local może być dowolną poprawną nazwą zmiennej lokalnej.
źródło
[key: string]: any;
do,Class
aby obejść ten problem.W przypadku, gdy chcesz uzyskać odpowiedź funkcji i ustawić ją w zmiennej, możesz użyć jej w szablonie w następujący sposób,
ng-container
aby uniknąć modyfikacji szablonu.Metoda w komponencie może być podobna
źródło
Jeśli potrzebujesz wsparcia autouzupełniania z poziomu szablonów z Angular Language Service :
Synchroniczny:
Za pomocą potoku asynchronicznego:
źródło
Używam kątowego 6x i skończyło się na tym, że użyłem poniżej fragmentu kodu. Mam scenerię, w której muszę znaleźć użytkownika z obiektu zadania. zawiera tablicę użytkowników, ale muszę wybrać przypisanego użytkownika.
źródło
Jest to o wiele prostsze, bez potrzeby niczego dodatkowego. W moim przykładzie deklaruję zmienną „open”, a następnie jej używam.
źródło
"?"
ponieważ miałem komunikat „Wartość identyfikatora” nie jest zdefiniowana ”jak to =>„ open? .Value ”Ale to działa !!Podobało mi się podejście polegające na stworzeniu w tym celu dyrektywy (dobre połączenie @yurzui).
Skończyło się na tym, że znalazłem dyrektywę Angular „let” w artykule Medium, która ładnie wyjaśnia ten problem i proponuje niestandardową dyrektywę let, która ostatecznie świetnie działa w moim przypadku użycia z minimalnymi zmianami kodu.
Oto sedno (w momencie publikowania) moich modyfikacji:
Moje główne zmiany to:
appLet: T
naappLet: T | null
Nie jestem pewien, dlaczego zespół Angular nie tylko wydał oficjalną dyrektywę ngLet, ale co tam.
Oryginalny kod źródłowy trafia do @AustinMatherne
źródło
Krótka odpowiedź, która komuś pomaga
* Można jednak użyć dekoratora ViewChild, aby odwołać się do niego wewnątrz komponentu.
Odwołanie do zmiennej firstNameInput wewnątrz komponentu
Następnie możesz użyć this.nameInputRef w dowolnym miejscu w swoim Component.
Praca z szablonem ng
W przypadku ng-template jest nieco inaczej, ponieważ każdy szablon ma swój własny zestaw zmiennych wejściowych.
https://stackblitz.com/edit/angular-2-template-reference-variable
źródło
Dla tych, którzy zdecydowali się zastosować dyrektywę strukturalną jako zamiennik
*ngIf
, należy pamiętać, że kontekst dyrektywy nie jest domyślnie sprawdzany pod względem typu. Aby utworzyć bezpieczną dyrektywę typungTemplateContextGuard
należy dodać właściwość, patrz Pisanie kontekstu dyrektywy . Na przykład:Dyrektywa może być używana tak samo
*ngIf
, z tym wyjątkiem, że może przechowywać fałszywe wartości:Jedyną wadą w porównaniu z
*ngIf
tym jest to, że Angular Language Service nie jest w stanie ustalić typu zmiennej, więc nie ma uzupełniania kodu w szablonach. Mam nadzieję, że zostanie to wkrótce naprawione.źródło