Estou interessado em saber qual é o requisito / caso de uso para querer alterar o nome de um parâmetro de ligação como este exemplo?
LDJ 26/07
29
É apenas para evitar repetir algo como tab [elemento] .val por instância. Eu sei que posso resolver o problema no componente, mas eu estava apenas olhando como fazer no modelo (mesmo que eu não tenha essa solução).
Scipion
2
@LDJ caso de uso de uma amostra: eficiência. Use a amostra de stackblitz.com/angular/… <mat-checkbox [marcada] = "descendantsAllSelected (node)" [indeterminado] = "descendantsPartiallySelected (node)" (change) = "todoItemSelectionToggle (node)"> {{node. item}} </mat-checkbox> de fato, os descendentesPartiallySelected () chama descendantsAllSelected (). Isso significa que em algum momento descendentesAllSelected é chamado duas vezes. Se houver uma variável local, isso pode ser evitado.
precisa saber é o seguinte
3
<div *ngIf="{name:'john'} as user1; let user"> <i>{{user1|json}}</i> <i>{{user|json}}</i> </div>
Dasfdsa 19/03/19
@dasfdsa Eu acredito user1 === user, assim você faz *ngIf="{name:'john'} as user1ou *ngIf="{name:'john'};let usercomo na resposta do yurzui .
CPHPython
Respostas:
169
Atualizar
Podemos apenas criar uma diretiva como *ngIfe chamá-la*ngVar
isso vai funcionar na maioria dos casos, mas não é uma solução geral, uma vez que se baseia em variableser truthy
Keith
6
@ Keith Obrigado por apontar isso. Você pode dar uma olhada na minha resposta atualizada
yurzui
3
Essa deve ser a nova resposta, pois 1) é mais moderna que a outra solução 2) resume as solicitações de recebimento vinculadas na resposta atual e economiza muito tempo 3) inclui os exemplos em linha e não por link externo. Obrigado por mostrar isso. AFAIK qualquer objeto envolvido {}será avaliado como verdadeiro, portanto, esta solução é bastante robusta.
precisa saber é o seguinte
4
Por exemplo, botões expansíveis: *ngIf="{ expanded: false } as scope"e, se você estiver usando o bootstrap, poderá usar [ngClass]="{ 'in': scope.expanded }"e, em (click)="scope.expanded = !scope.expanded"vez de adicionar algo aos seus js/ tsarquivos.
Foi com isso que eu instintivamente - ele também funciona *ngFor="let a of [(someStream$ | async).someA]. Eu acho que usado com um <ng-container>que serve o trabalho muito bem!
Angelos Pikoulas
1
No caso de *ngFor, lembre-se de que todo o conteúdo aninhado será recriado se o valor da variável for alterado, até você especificar uma trackByfunção que retorne o mesmo ID para todos os valores.
Valeriy Katkov
72
Você pode declarar variáveis no código html usando um templateelemento no Angular 2 ou ng-templateno Angular 4+.
Os modelos têm um objeto de contexto cujas propriedades podem ser atribuídas a variáveis usando leta sintaxe de ligação. Observe que você deve especificar uma saída para o modelo, mas pode ser uma referência a si mesma.
Para fazê-lo funcionar, tive que alterar seu código de '<template ...' para '<ng-template ...'.
Humppakäräjät
2
Sim, você só pode usar <template>no Angular 2. Você pode usar um <template>ou outro <ng-template>no Angular 4, mas deve usar apenas <ng-template>. Angular 5 caiu suporte para <template>.
Steven Liekens 01/01
Para que serve t?
matttm
1
@matttm #té uma variável de modelo que armazena o ng-template. É usado [ngTemplateOutlet]="t"para fazer a referência do modelo ng em si.
Steven Liekens
Isso é bizare, mas funciona! Angular deve tornar isso mais simples, com uma diretiva de variável interna. Obrigado.
Existem variáveis de modelo, mas não há suporte para atribuir valores arbitrários. Eles só podem ser usados para se referir aos elementos aos quais são aplicados, nomes exportados de diretivas ou componentes e variáveis de escopo para diretivas estruturais como ngFor,
Não seria possível criar uma diretiva estrutural para isso?
Scipion
Se você precisar disso repetidamente, uma diretiva poderá fazer o que você deseja. Uma diretiva estrutural cria sua própria visão, provavelmente não é isso que você deseja.
Günter Zöchbauer
1
@ GünterZöchbauer, coisas muito boas. Eu sei que provavelmente é uma prática melhor ter variáveis calculadas / preparadas no component.tsarquivo. Mas é muito mais fácil tê-los à vista em alguns casos devido a um esquema de sincronização que estou implementando em todo o meu aplicativo. Estou aproveitando as regras de referência de javascript quando variáveis diferentes apontam para o mesmo objeto.
AmmarCSE
Estou recebendo um erro como There is no directive with "exportAs" set to "var". Alguém pode me dizer que erro eu cometi? Eu usei a diretiva acima.
Partha Sarathi Ghosh
Talvez você não tenha adicionado a diretiva a declarations: [...]de @NgModule(). Se este não for o problema, crie uma nova pergunta e forneça o código que permite diagnosticar o problema.
Günter Zöchbauer
11
Aqui está uma diretiva que escrevi que expande o uso do parâmetro decorador exportAs e permite que você use um dicionário como uma variável local.
import{Directive,Input}from"@angular/core";@Directive({
selector:"[localVariables]",
exportAs:"localVariables"})exportclassLocalVariables{@Input("localVariables")set localVariables(struct: any ){if(typeofstruct==="object"){for(var variableName instruct){this[variableName]=struct[variableName];}}}constructor(){}}
Você pode usá-lo da seguinte maneira em um modelo:
como este, mas * é reservado para directivas estruturais que esta não é, de qualquer maneira +1
danday74
7
Caso deseje obter a resposta de uma função e configurá-la em uma variável, você pode usá-la da seguinte forma no modelo, ng-containerpara evitar a modificação do modelo.
<ng-container *ngIf="methodName(parameters) as respObject">
{{respObject.name}}
</ng-container>
E o método no componente pode ser algo como
methodName(parameters: any): any {return{name:'Test name'};}
@Amirreza, para ser mais preciso, estou usando o ElementRef para armazenar temporariamente um valor.
Jack Rus
Impressionante! Eu tive que usar "?"porque tinha a mensagem "Identificador 'valor' não está definido" como este => "aberto? .Valor" Mas está funcionando !!
A. Morel
2
Estou usando 6x angular e acabei usando o trecho abaixo. Eu tenho um cenário onde eu tenho que encontrar usuário de um objeto de tarefa. Ele contém vários usuários, mas eu tenho que escolher o usuário atribuído.
Gostei da abordagem de criar uma diretiva para fazer isso (boa chamada @yurzui).
Acabei encontrando uma diretiva angular "let" de artigo Médio, que explica bem esse problema e propõe uma diretiva let personalizada que acabou funcionando muito bem no meu caso de uso com alterações mínimas de código.
Aqui está a essência (no momento da postagem) com minhas modificações:
Para aqueles que decidiram usar uma diretiva estrutural como uma substituição *ngIf, lembre-se de que o contexto da diretiva não é verificado por tipo. Para criar uma ngTemplateContextGuardpropriedade de diretiva de segurança de tipo deve ser adicionada, consulte Digitando o contexto da diretiva . Por exemplo:
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;}
A diretiva pode ser usada da mesma maneira *ngIf, exceto que pode armazenar valores falsos :
<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>
A única desvantagem comparada *ngIfé que o Angular Language Service não pode descobrir o tipo de variável, portanto, não há conclusão de código nos modelos. Espero que seja corrigido em breve.
<div *ngIf="{name:'john'} as user1; let user"> <i>{{user1|json}}</i> <i>{{user|json}}</i> </div>
user1 === user
, assim você faz*ngIf="{name:'john'} as user1
ou*ngIf="{name:'john'};let user
como na resposta do yurzui .Respostas:
Atualizar
Podemos apenas criar uma diretiva como
*ngIf
e chamá-la*ngVar
ng-var.directive.ts
com esta
*ngVar
diretiva, podemos usar o seguinteou
ou
ou
Exemplo de Plunker Angular4 ngVar
Veja também
Resposta original
Angular v4
1)
div
+ngIf
+let
2)
div
+ngIf
+as
Visão
component.ts
3) Se você não deseja criar um invólucro como
div
você pode usarng-container
Visão
Como @Keith mencionado nos comentários
Consulte a atualização para outra abordagem.
fonte
variable
ser truthy{}
será avaliado como verdadeiro, portanto, esta solução é bastante robusta.*ngIf="{ expanded: false } as scope"
e, se você estiver usando o bootstrap, poderá usar[ngClass]="{ 'in': scope.expanded }"
e, em(click)="scope.expanded = !scope.expanded"
vez de adicionar algo aos seusjs
/ts
arquivos.*ngIf
em vez de coisas ngvar personalizado): github.com/angular/angular/issues/14985Feio, mas:
Quando usado com tubo assíncrono:
fonte
*ngFor="let a of [(someStream$ | async).someA]
. Eu acho que usado com um<ng-container>
que serve o trabalho muito bem!*ngFor
, lembre-se de que todo o conteúdo aninhado será recriado se o valor da variável for alterado, até você especificar umatrackBy
função que retorne o mesmo ID para todos os valores.Você pode declarar variáveis no código html usando um
template
elemento no Angular 2 oung-template
no Angular 4+.Os modelos têm um objeto de contexto cujas propriedades podem ser atribuídas a variáveis usando
let
a sintaxe de ligação. Observe que você deve especificar uma saída para o modelo, mas pode ser uma referência a si mesma.Você pode reduzir a quantidade de código usando a
$implicit
propriedade do objeto de contexto em vez de uma propriedade customizada.O objeto de contexto pode ser um objeto literal ou qualquer outra expressão de ligação. Até canos parecem funcionar quando cercados por parênteses.
Exemplos válidos de
ngTemplateOutletContext
:[ngTemplateOutletContext]="{ aVariable: 123 }"
[ngTemplateOutletContext]="{ aVariable: (3.141592 | number:'3.1-5') }"
[ngTemplateOutletContext]="{ aVariable: anotherVariable }"
usar comlet-a="aVariable"
[ngTemplateOutletContext]="{ $implicit: anotherVariable }"
usar comlet-a
[ngTemplateOutletContext]="ctx"
ondectx
é uma propriedade públicafonte
<template>
no Angular 2. Você pode usar um<template>
ou outro<ng-template>
no Angular 4, mas deve usar apenas<ng-template>
. Angular 5 caiu suporte para<template>
.t
?#t
é uma variável de modelo que armazena ong-template
. É usado[ngTemplateOutlet]="t"
para fazer a referência do modelo ng em si.atualização 3
O problema 2451 foi corrigido no Angular 4.0.0
Veja também
atualização 2
Isto não é suportado.
Existem variáveis de modelo, mas não há suporte para atribuir valores arbitrários. Eles só podem ser usados para se referir aos elementos aos quais são aplicados, nomes exportados de diretivas ou componentes e variáveis de escopo para diretivas estruturais como
ngFor
,Consulte também https://github.com/angular/angular/issues/2451
Atualização 1
e inicialize como
ou
e use a variável como
(não testado)
#aVariable
cria uma referência para oVarDirective
(exportAs: 'var'
)var="abc"
instancia oVarDirective
e passa o valor da string"abc"
para sua entrada de valor.aVariable.var
lê o valor atribuído à entrada devar
diretivasvar
.fonte
component.ts
arquivo. Mas é muito mais fácil tê-los à vista em alguns casos devido a um esquema de sincronização que estou implementando em todo o meu aplicativo. Estou aproveitando as regras de referência de javascript quando variáveis diferentes apontam para o mesmo objeto.There is no directive with "exportAs" set to "var"
. Alguém pode me dizer que erro eu cometi? Eu usei a diretiva acima.declarations: [...]
de@NgModule()
. Se este não for o problema, crie uma nova pergunta e forneça o código que permite diagnosticar o problema.Aqui está uma diretiva que escrevi que expande o uso do parâmetro decorador exportAs e permite que você use um dicionário como uma variável local.
Você pode usá-lo da seguinte maneira em um modelo:
É claro que #local pode ser qualquer nome de variável local válido.
fonte
[key: string]: any;
aoClass
para contornar isso.Gostaria de sugerir o seguinte: https://medium.com/@AustinMatherne/angular-let-directive-a168d4248138
Esta diretiva permite que você escreva algo como:
fonte
Caso deseje obter a resposta de uma função e configurá-la em uma variável, você pode usá-la da seguinte forma no modelo,
ng-container
para evitar a modificação do modelo.E o método no componente pode ser algo como
fonte
Se você precisar de suporte de preenchimento automático de seus modelos no Angular Language Service :
Síncrono:
Usando pipe assíncrono:
fonte
É muito mais simples, sem necessidade de mais nada. No meu exemplo, declaro a variável "open" e depois a uso.
fonte
"?"
porque tinha a mensagem "Identificador 'valor' não está definido" como este => "aberto? .Valor" Mas está funcionando !!Estou usando 6x angular e acabei usando o trecho abaixo. Eu tenho um cenário onde eu tenho que encontrar usuário de um objeto de tarefa. Ele contém vários usuários, mas eu tenho que escolher o usuário atribuído.
fonte
Gostei da abordagem de criar uma diretiva para fazer isso (boa chamada @yurzui).
Acabei encontrando uma diretiva angular "let" de artigo Médio, que explica bem esse problema e propõe uma diretiva let personalizada que acabou funcionando muito bem no meu caso de uso com alterações mínimas de código.
Aqui está a essência (no momento da postagem) com minhas modificações:
Minhas principais mudanças foram:
appLet: T
paraappLet: T | null
Não sei por que a equipe Angular não fez apenas uma diretiva ngLet oficial, mas o que quer.
O crédito do código fonte original vai para @AustinMatherne
fonte
Resposta curta que ajuda a alguém
* No entanto, você pode usar o decorador do ViewChild para referenciá-lo dentro do seu componente.
Variável de referência firstNameInput dentro de Component
Depois disso, você pode usar this.nameInputRef em qualquer lugar dentro do seu Component.
Trabalhando com ng-template
No caso do ng-template, é um pouco diferente porque cada modelo possui seu próprio conjunto de variáveis de entrada.
https://stackblitz.com/edit/angular-2-template-reference-variable
fonte
Para aqueles que decidiram usar uma diretiva estrutural como uma substituição
*ngIf
, lembre-se de que o contexto da diretiva não é verificado por tipo. Para criar umangTemplateContextGuard
propriedade de diretiva de segurança de tipo deve ser adicionada, consulte Digitando o contexto da diretiva . Por exemplo:A diretiva pode ser usada da mesma maneira
*ngIf
, exceto que pode armazenar valores falsos :A única desvantagem comparada
*ngIf
é que o Angular Language Service não pode descobrir o tipo de variável, portanto, não há conclusão de código nos modelos. Espero que seja corrigido em breve.fonte