【问题标题】:How to change the views dynamically from one component to another in angular4如何在angular4中动态地将视图从一个组件更改为另一个组件
【发布时间】:2018-05-02 17:41:13
【问题描述】:

在我的应用程序中,我需要根据父组件值将视图从一个组件更改为另一个。

视图结构

<app-component>
<app-common></app-common>
</app-component>

这里我把通用组件称为app组件的子组件。

<app-common>
<app-grid></app-grid>
</app-common>

这里我将网格组件作为公共组件的子组件

common.html

   <div class="accordion col-sm-12" id="accordion1" *ngFor='let data of dropdownData; let i=index'>
            <div class="accordion-group">

                <div class="accordion-heading">
                    <a class="accordion-toggle h6" (click)="getCategory(categorycode.value)" data-toggle="collapse" data-parent="#accordion1" href="#collapseTwo + i">
                        {{data?.CAMD_ENTITY_DESC}}
                        <input type="hidden" #categorycode value="{{data?.PROD_PRCATG_CODE}}">
                    </a>
                </div>

                <div *ngFor='let group of data.group; let j=index' id="collapseTwo + i" class="accordion-body collapse" style="margin-left:10px">
                    <div class="accordion-inner">
                        <div class="accordion" id="accordion2">
                            <div class="accordion-group">

                                <div class="accordion-heading">
                                    <a class="accordion-toggle" (click)="getGroup(groupcode.value)" data-toggle="collapse" data-parent="#accordion2" [href]="'#collapseInnerTwo' + j">
                                        {{group?.CAMD_PRGRP_DESC}}
                                        <input type="hidden" #groupcode value="{{group?.PROD_PRGRP_CODE}}">
                                    </a>
                                </div>

                                <div [id]="'collapseInnerTwo' + j" class="accordion-body collapse" style="margin-left:10px;margin-top:3px">

                                    <div class="accordion-inner" style="cursor: pointer;" (click)="getSubgruop(subgroupcode.value)" *ngFor='let subgroup of group?.subgroup; let i=index'>
                                        {{subgroup?.CAMD_PRSGRP_DESC}}
                                        <input type="hidden" #subgroupcode value="{{subgroup?.PROD_PRSGRP_CODE}}">
                                    </div>
                                </div>

                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
         <app-grid></app-grid>

这是一个来自该用户的手风琴,可以选择类别、组、子组等选项,因此每个用户选择网格组件中需要的值来显示视图(API 调用将从网格组件中的 db 获取每个选定值的数据) 在用户选择选项时动态显示。

common.component.ts

export class CommonComponent {

  categorycode :string ='';
  groupcode :string= '';
  subgroupcode:string='';

  constructor(private router: Router, private CartdataService: CartdataService) { }

  ngOnInit() {}

  public getCategory(categorycode){
    this.CartdataService.get_Category_Code(categorycode);
  }
  public getGroup(groupcode){
    this.CartdataService.get_Group_Code(groupcode); 
  }
  public getSubgruop(subgroupcode){
    this.CartdataService.get_Group_Code(subgroupcode); 
  }

}

grid.component.ts

  export class GridComponent {

  @Input() C_code: string;
  @Input() G_code: string;
  @Input() SG_code: string;

  products: any;



  constructor(private CartdataService: CartdataService, private router: Router) {
    this.router.events.subscribe(
      () => window.scrollTo(0, 0));
  }

  ngOnInit() {

    this.CartdataService.get_Selected_Category_Of_Products(this.C_code,
      this.G_code, this.SG_code).subscribe(
        data => {
          this.products = data;
        });
      }

  ngOnChanges(change: SimpleChange) {
    this.CartdataService.get_Selected_Category_Of_Products(this.C_code,
      this.G_code, this.SG_code).subscribe(
        data => {
          this.products = data;
        });
  }

}

grid.html

<div class="row">

    <div class="col-sm-4 column" *ngFor="let product of products;let i =index;">
        <div class="card">
            <div class="card-img-top card-img-top-250 one">
                <img routerLink="/my-cart" class="img-fluid" [src]="product['IMAGE_PATH_1']" alt="image">
                <img routerLink="/my-cart" class="img-fluid two" [src]="product['IMAGE_PATH_2']" alt="image">
            </div>
            <div class="card-block pt-2">
                <div class="col-sm-12 text-center card-text">
                    <span #Pname1>{{product?.ITEM_DESCRIPTION}}</span>
                    <br>
                    <input type="hidden" value="{{product?.PRODUCT_CODE}}">
                    <p class="font-weight-bold text-primary">{{product?.PRODUCT_PRICE}} &#8377;</p>
                </div>
                <button type="button" class="btn  btn-primary col-sm-12 corner" routerLink="/my-cart" (click)="getProductName(Pname1)">
                    <strong>View Details</strong>
                </button>
            </div>
        </div>
    </div>

</div>

这里将用户选择的下拉值传递给服务文件。

正如我上面提到的,网格组件是公共组件的子组件,因此在页面加载时,网格组件会根据公共组件发送的服务文件中的值显示视图。

现在当用户从公共组件的下拉列表中选择一些值时,这些值将传递给服务文件,基于这些值我从服务文件调用 API。

现在我想做的是当新值从公共组件进入服务文件时,我想根据新值更改网格组件的视图。

如果可以,请指导我解决。 谢谢

【问题讨论】:

  • -> 为什么不将在此处更改的值作为模型传递并处理模型更改?
  • @VeselinDavidov 如何在模型值发生变化时触发网格组件

标签: angular typescript


【解决方案1】:

在 GridComponent 中创建一个 @input 字段,然后从父组件传递值。类似的东西:

 @Input() inputValue: string;

然后你就这样调用组件

<app-grid [inputValue]="valueFromCommon" ></app-grid>

这里的共同价值是未来价值。我在这里使用了两种方式绑定,但如果您不希望它变回来,您可以使用一种方式绑定。

那么要处理更改,您有两种选择。

  • 首选方法:)

在网格组件中你可以创建这样的方法(基本上是在变化时实现)

 ngOnChanges(changes: SimpleChanges) {
        console.log("new value:",changes);
    }

这里的更改对象保存了已更改的值、之前的值和新的值。你可以随心所欲地处理它。

  • 我不推荐的另一种方法,因为它类似于 hack

为 @input 字段创建 getter 和 setter 并在那里处理更改

private _inputValue: string;

@Input() set inputValue(value: string) {    
   this._inputValue= value;
  // process new value here    
}

get inputValue(): string {    
    return this._inputValue;    
}

----- 使用实际代码编辑您的问题-----

在您的示例中,您从服务加载网格组件中的数据的方式使其与父组件分离。您从注入的服务加载 ngOnInit() 中的所有内容。相反,您应该从父组件传递您想要的值。

例如将这些更改为输入

export class GridComponent {

 @Input()  C_code: string;
 @Input()  G_code: string;
 @Input()  SG_code: string;

然后在 ngOnInit 中不要将它们从服务中取出并使用来自父组件的那些

ngOnInit() {
  this.CartdataService.get_Selected_Category_Of_Products(this.C_code, 
          this.G_code, this.SG_code).subscribe(
        data => {
            this.products = data;
            console.log(data);
   });
}

然后调用网格组件使用:

  <app-grid [C_code]="categorycode" [G_code]="groupcode" [SG_code]="subgroupcode" ></app-grid>

这样您将从公共组件中选择的值传递给网格组件。现在为了处理这些值的更改(更改会自动传播到组件,但如果您有更改的外部逻辑,则需要添加它)。所以在网格组件中添加该方法:

ngOnChanges(changes: SimpleChanges) {
             this.CartdataService.get_Selected_Category_Of_Products(this.C_code, 
              this.G_code, this.SG_code).subscribe(
            data => {
                this.products = data;
                console.log(data);
       });
     }

这基本上与 ngOnInit 相同 - 查询服务。这就是您想要在属性更改时执行的操作 - 重新查询服务

【讨论】:

  • 确定上传。你没有得到哪个部分?创建一个输入字段,您可以将值传递给组件。制作 ngOnChanges(changes: SimpleChanges) 方法来处理更改并进行一些处理(如果需要)
  • 同时添加html
  • 我写了我的评论,但我还没有测试过。它应该工作。您可以尝试一下并玩一下。基本上,您需要从父组件传递值,而不是从服务中获取它们并处理 onChange 事件
  • 我试图检查从普通抛出控制台传递给网格组件的值,但它显示一个空行......我需要做什么
  • 好吧,我给了你方法——对不起,我懒得写你的程序;)玩一会儿,它会工作的。
猜你喜欢
  • 2020-04-26
  • 2021-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-16
  • 2018-05-04
  • 1970-01-01
  • 2018-12-20
相关资源
最近更新 更多