如何防止在 Angular 中的 if-else 条件下重新构造组件

How to prevent re-construction of components in if-else condition in Angular

我是一名 ReactJS 开发人员,刚刚进入 Angular4 俱乐部。我正在使用具有超级简单条件的基本条件语句,就像这样:

<div class="app-component">

    <app-country *ngIf="condition"></app-country>         
    <app-country  *ngIf="!condition"></app-country> 
    <div>condition is [{{condition}}]</div>
    <button (click)="condition=!condition">Toggle condition</button>

</div>

这是我的 app.component.ts 文件。而另一个 app-country 只是 ng g 个创建的组件并且仅包含 <p> hello country</p>。 App.component.ts 中的条件每次都会切换。问题是 app-country 在条件触发时一直重新构造而不是重新渲染。例如,第一次 condition 从 undefined 变为 true 然后 app-country 将被构造和渲染。条件第二次变为假, app-country 被构造和渲染。但它应该重新渲染最后构造的组件。


我不知道这是一个问题,还是 Angular 的工作方式。我的意思是 Angular 有什么方法可以按照我希望的方式解决这个问题吗?就像 ReactJS 中的 keys 告诉 React 这是组件键,React 将其识别为组件实例的 id。像这样

<AppCountry key='app-country'/>

如有任何帮助,我们将不胜感激。谢谢

您可以使用 hidden 属性代替 *ngIf 并将您的代码更改为:

<div class="app-component">

    <app-country [hidden]="condition"></app-country>         
    <app-country  [hidden]="!condition"></app-country> 
    <div>condition is [{{condition}}]</div>
    <button (click)="condition=!condition">Toggle condition</button>

</div>

此属性将帮助您在不触发构造函数的情况下隐藏和显示 dom

Vala Khosravi 的回答是正确的,只是为了给你解释一下。

NgIf 指令是所谓的结构指令(如 ngFor),这意味着它会更改模板。在 ngIf 情况下,它从模板中删除组件或将其添加到模板化(基于条件)。 如果您从 angular 中的模板中删除组件,您将销毁它。

因此,您可以像 Vala Khosravi 所说的那样更改其 visibility,或者如果您只想显示相同的组件但具有不同的数据,则可以使用 Input。例如带有配置数据的对象,只根据条件更新输入。

因此,如果您想根据条件显示不同的名称和标志,您有两种选择。 1. 一个 input,对象,带有名称和标志 属性。这可能更容易使用,但如果您需要检测输入的变化,angular 不知道对象的属性发生了变化,因为它是同一个引用。简单的解决方法是传播对象或以任何其他方式创建新的引用。

<app-country [countryData]="countryData"></app-country>

在 AppComponent 中:

this.countryData = {
    name: 'Ukuleleland',
    flag: 'assets/images/ukuleleland.png',
};

在AppCountryComponent中:(输入需要从@angular/core导入)

@Input() countryData;

并在模板中:

<div>
    <span>country name: {{countryData.name}}</span>
    <img [src]="countryData.flag">
</div>
  1. 同样的事情,但有两个输入:

剩下的你就知道了。

还有一件事,我的小毛病:<div class="app-component"> 没有必要。您将在模板中拥有:

<app-component>
    <div class="app-component"></div>
    ...
</app-component>

如果需要设置样式,可以使用 :host() {display:block;} 选择器。如果您需要动态添加 class 或其他内容,您可以使用 @HostBinding.

希望对您有所帮助,祝您 angular.

好运