【问题标题】:What is the best approach to hide/show component depending on some condition in Angular 8根据Angular 8中的某些条件隐藏/显示组件的最佳方法是什么
【发布时间】:2020-06-10 02:10:56
【问题描述】:

各位,谢谢你们的帮助。在获得大量建议并混合并匹配所有这些建议的代码后,我能够解决早期的问题。但是,在控制台中使用 @ViewChild 装饰器后出现以下错误。

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'count1'. Current value: 'count2'.

我的父 ts 文件代码如下

import { Component, OnInit, Input, ViewEncapsulation, ViewChild, AfterViewInit} from '@angular/core';
import { NagivationComponent } from '../nagivation/nagivation.component';
import { CensusComponent } from '../your-data/census/census.component';
import { ApplicationComponent } from '../your-data/application/application.component';

@Component({
  selector: 'app-your-data',
  templateUrl: './your-data.component.html',
  styleUrls: ['./your-data.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class YourDataComponent implements AfterViewInit{
  @Input() step;

  count:string = 'count1';
  constructor() {

  }
  @ViewChild(CensusComponent, {static: false}) census: CensusComponent;
  ngAfterViewInit() {
    this.count = this.census.getSection(); 
  }      
}

your-data.component.html 代码如下

<div [ngSwitch]="count">
   <app-census *ngSwitchCase="'count1'"></app-census>
   <app-application *ngSwitchCase="'count2'"></app-application>
</div>

【问题讨论】:

标签: angular angular-services angular-components


【解决方案1】:

只需使用 ngIf 并在条件下使用计数,单击下一步按钮时计数会增加

<div class='container'>
  <div class='row'>
    <div class='setup-content'>
      <h1>Confirm Data/Answer Questions</h1>
      <p>Please answer all questions below. If you have questions about the data provided on this screen, please contact << Broker >> at << Phone >> or << Email >>.</p>
      <app-census *ngIf="count === 1"></app-census>
      <app-census1 *ngIf="count === 2"></app-census1>
    </div>
  </div>
</div>

【讨论】:

    【解决方案2】:

    使用*ngIf根据步骤显示组件, 试试:

    <div class='container'>
      <div class='row'>
        <div class='setup-content'>
          <h1>Confirm Data/Answer Questions</h1>
          <p>Please answer all questions below. If you have questions about the data provided on this screen, please contact << Broker >> at << Phone >> or << Email >>.</p>
          <app-census *ngIf="step == 1"></app-census>
          <app-census1 *ngIf="step == 2"></app-census1>
        </div>
      </div>
    </div>
    

    【讨论】:

    • 获取以下无法绑定到“ngif”,因为它不是“app-census”的已知属性。 *ngIf 只接受布尔值。这里我需要检查一个条件。
    • @PiyaliGhosh 您需要在您的 app.module 或您声明组件的模块中添加 CommonModule
    【解决方案3】:

    您可以使用*ngIf*ngSwitchCase 指令根据条件显示组件。

    模板:

    <div [ngSwitch]="step">
      <div *ngSwitchCase="'step1'"><app-census1></app-census1></div>
      <div *ngSwitchCase="'step2'"><app-census2></app-census2></div>
      <div *ngSwitchCase="'step3'"><app-census3></app-census3></div>
      <div *ngSwitchCase="'step4'"><app-census4></app-census4></div>
      <div *ngSwitchDefault>Default</div>
    </div>
    

    组件

    import { Component, OnInit, Input, ViewEncapsulation } from '@angular/core';
    import { NagivationComponent } from '../nagivation/nagivation.component';
    
    @Component({
      selector: 'app-your-data',
      templateUrl: './your-data.component.html',
      styleUrls: ['./your-data.component.css'],
      encapsulation: ViewEncapsulation.None
    })
    export class YourDataComponent implements OnInit {
      @Input() step;
      count:number;
      step: string;
    
      constructor() { }
    
      ngOnInit() {
        // here set this.step = 'step1' | 'step2' | 'step3' | 'step4'      
      }
    }
    

    对于基于步进的应用程序,您可以参考here 获取示例应用程序。在该应用程序中启用线性模式将确保您需要输入一些数据才能继续下一步。

    【讨论】:

    • 获取以下错误 src/app/your-data/your-data.component.ts:18:29 - 错误 TS2363:算术运算的右侧必须是“任意”类型'、'number'、'bigint' 或枚举类型。 18 this.count = 'count1' | 'count2' | 'count3' | 'count4'
    • 您需要根据您所在的步骤设置this.step的值。例如,如果您在第 1 步,则设置this.step = 'step1';。这将显示组件&lt;app-census1&gt;&lt;/app-census1&gt;。然后当你进入第 2 步时,设置this.step = 'step2';。这将显示&lt;app-census2&gt;&lt;/app-census2&gt; 等等。 this.step = 'step1' | 'step2' | 'step3' | 'step4' 应该是一个占位符,告诉你this.step 可以取什么值。
    • 另外this.count = 'count1' | 'count2' | 'count3' | 'count4' 来自另一个答案。我使用变量this.step
    【解决方案4】:

    当您有两个以上的步骤时,您可以使用*ngSwitch*ngSwitchCase 来获得更简洁的方法:

    <div class='container'>
      <div class='row'>
        <div class='setup-content'>
          <h1>Confirm Data/Answer Questions</h1>
          <p>Please answer all questions below. If you have questions about the data provided on this screen, please contact << Broker >> at << Phone >> or << Email >>.</p>
          <ng-container [ngSwitch]="count">
              <app-census *ngSwitchCase="1"></app-census>
              <app-census1 *ngSwitchCase="2"></app-census1>
          </ng-container>
        </div>
      </div>
    </div>

    【讨论】:

    • 我遇到错误 src/app/your-data/your-data.component.html:7:36 - 错误 TS2551:“YourDataComponent”类型上不存在属性“count1”。您指的是 “count” 吗? 7 ~~~~~~
    • 你必须将它设置为 *ngSwitchCase="1",而不是 *ngSwitchcase="count1"。
    • 这个问题已经解决了。然而,又出现了一个问题。使用 ViewChild 并相应地更新我的 DOM 后,我遇到了以下错误。 core.js:5845 错误错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:'count1'。当前值:'count2'。
    • @PiyaliGhosh 这是因为您正在更新生命周期挂钩、ngOnInit、ngOnChanges 等中的计数值。
    【解决方案5】:

    您可以使用 *ngTemplateOutlet 根据计数变量显示组件。

     <div class='container'>
              <div class='row'>
                <div class='setup-content'>
                  <h1>Confirm Data/Answer Questions</h1>
                  <p>Please answer all questions below. If you have questions about the data provided on this screen, please contact << Broker >> at << Phone >> or << Email >>.</p>
               <div *ngif="count == 1"> 
     <app-census></app-census>
    <ng-container *ngTemplateOutlet="template"></ng-container>
               </div>
             <div *ngif="count == 2"> 
     <app-census1></app-census1>
    <ng-container *ngTemplateOutlet="template"></ng-container>
               </div>
                </div>
              </div>
            </div>
    
        <ng-template #template>
          <router-outlet>
          </router-outlet>
        </ng-template>
    

    【讨论】:

      【解决方案6】:

      上述问题已解决,将模式从 dev 更改为 prod。 在 main.ts 中

      enableProdMode();
      

      请删除 if 条件。 以下是我的整个解决代码

      父组件 .html 文件

      <div [ngSwitch]=count>
            <app-census *ngSwitchCase="'count1'"></app-census>
            <app-application *ngSwitchCase="'count2'"></app-application>
         </div>
      

      父组件文件

      import { Component, OnInit, Input, ViewEncapsulation, ViewChild, AfterViewInit} from '@angular/core';
      import { NagivationComponent } from '../nagivation/nagivation.component';
      import { CensusComponent } from '../your-data/census/census.component';
      import { ApplicationComponent } from '../your-data/application/application.component';
      
      @Component({
        selector: 'app-your-data',
        templateUrl: './your-data.component.html',
        styleUrls: ['./your-data.component.css'],
        encapsulation: ViewEncapsulation.None
      })
      export class YourDataComponent implements AfterViewInit{
        @Input() step;
      
        count:string = 'count1';
        constructor() {
      
        }
        @ViewChild(CensusComponent, {static: false}) census: CensusComponent;
        ngAfterViewInit() {
          this.count = this.census.getSection(); 
        }
      
      }
      

      子组件html

      <button class="sub btn btn-primary btn-lg nbtn" type="button" (click)="getSection()"><span>NEXT</span></button>
      

      子组件文件

      import { Component, OnInit, Input } from '@angular/core';
      import { YourDataComponent } from '../your-data.component';
      @Component({
        selector: 'app-census',
        templateUrl: './census.component.html',
        styleUrls: ['./census.component.css']
      })
      export class CensusComponent implements OnInit {
        @Input() count:string;
        getSection(){
          this.count = 'count2';
          return this.count;
        }
        constructor() {
      
        }
      
        ngOnInit(): void {
        }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2021-09-19
        • 2019-09-26
        • 2015-07-27
        • 1970-01-01
        • 1970-01-01
        • 2023-01-10
        • 1970-01-01
        • 1970-01-01
        • 2011-12-25
        相关资源
        最近更新 更多