Angular父子组件:在父单击上加载子组件 [英] Angular Parent-Child Component: Load Child on Parent click

查看:120
本文介绍了Angular父子组件:在父单击上加载子组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有文章列表和文章详细信息组件.

I have article list and article detail component.

文章列表: -文章清单.以表格的形式加载到html中.处理了点击事件并设置了商品ID -使用商品ID属性向商品详细信息发送信号,以将其作为@Input属性加载.

Article List: -- list of articles. load into html as a table. handled a click event and set the article id -- use the article id property to send a signal to article detail to load as @Input property.

文章详细信息: -@Input属性从列表中侦听并注册ng-OnChange事件以处理任何更改 -加载文章详细信息视图模型(具有更多详细信息) -使用反应性表单加载所有属性以更正表单组. -使用示例属性并在具有Reactive表单属性的UI中显示,只是要知道@Input属性正在从列表中获取正确的值.

Article Detail: -- @Input property listen from list and register ng-OnChange event to handled any change -- Load the article detail view model (with more detail) -- Use Reactive Form to load all the property to correct formgroup. -- Use sample property and display in UI with Reactive form property just to know the @Input property is getting the correct value from list.

现在,我在Sample属性中获得了正确的值.并且从文章详细信息"更改事件中调用服务方法.它还设置了视图模型.但问题出在这里,视图"显示一键式旧数据.

Now, I am getting correct value in Sample property. and also the service method is getting called from Article Detail change event. It also set the view model. but the problem here, View display one click old data.

如果单击第二篇文章,则示例属性会正确更新,这证明我的详细信息组件会获取信息,并且最终视图模型也会在服务响应后得到更新.但是View会显示旧的View模型.

If I click the second article, my sample property updates correctly which proves that, my detail component gets the information and eventually view model also gets updated after service response. but View display the old View Model.

每次单击最后一次存储的viewmodel数据都将显示在View上.知道为什么吗? 这是代码:

Every click last stored viewmodel data is getting display on View. any idea why? Here is code:

 **#Article-List Component.ts**   
 @Component({
     selector: 'admin-article-list',
     templateUrl: './article-list.component.html',
     styleUrls: ['./article-list.component.css']
 })
 export class ArticleListComponent extends BaseImplementationComponent {
     public selectedArticleId: string;

     articleClick(event: Event, articleViewModel: ArticleViewModel) {
         this.selectedArticleId = articleViewModel.articleId;
     }
 }

 **#Article-List-Html**
 <div *ngFor="let article of articles">
    <div class="row article" (click)="articleClick($event, article)">
       <div class="col-xs-3 col-sm-3">
          <a href='{{article.articleId}}'>{{article.articleId}}</a>
       </div>
    </div>
    <div>
       <admin-article-detail *ngIf="isReadyToLoad" [articleId]="selectedArticleId"></admin-article-detail>
    </div>
 </div>

 **#Article-Detail-Component.ts**
 @Component({
    selector: 'admin-article-detail',
    templateUrl: './article-detail.component.html',
    styleUrls: ['./article-detail.component.css']
 })
 export class ArticleDetailComponent extends BaseImplementationComponent {
    @Input()
    articleId: string;

    articleViewModel: ArticleViewModel;
    articleDetailFormGroup: FormGroup;

    constructor(private formBuilder: FormBuilder, private articleService: ArticleService) {super();

    this.createArticleDetailForm();
   }

    protected ngOnChangesAtBaseComponent(): void {
       this.loadArticleDetail();
       this.patchArticleDetailForm();
       this.articleIdComingfromParent = this.articleId;
    }

    private loadArticleDetail() {
       this.articleService.getArticle(this.articleId)
       .map(item => this.articleViewModel = item)
       .subscribe(
       (item) => {
          console.log(item);
          this.articleViewModel = item;
       },
       (err) => {
          console.log(err);
       });
    }

    private patchArticleDetailForm() {
       //console.log(this.articleViewModel.articleTitle);
       this.articleDetailFormGroup.get('articleBasicDetail').patchValue({ 
       articleTitle: this.articleViewModel.articleTitle });
    }

    private createArticleDetailForm() {
        this.articleDetailFormGroup = this.formBuilder.group({
           articleBasicDetail: this.formBuilder.group({
           articleTitle: ''
           })
        });
    }
 }


 **#Article-Detail-Html**
 <form class="form-horizontal" [formGroup]="articleDetailFormGroup">
    <div class="form-group" formGroupName="articleBasicDetail">
       <div class="col-sm-12">
          <label for="articleTitle" class="center-block">Street:
             <input type="text" id="articleTitle" class="form-control" formControlName="articleTitle">
             Updated from: {{articleIdComingfromParent}}
          </label>
       </div>
    </div>
</form>

推荐答案

我认为,如果输入的引用发生更改,子组件将触发更改,您会遇到此错误,因为您是直接更改输入的,这是一种解决方案您,使用OnPush检测策略和doCheck

i think the child component will trigger changes if the reference of the input changes, you have this error because you are changing the input directly, here is a solution for you, using OnPush detection strategy and doCheck

 @Component({
  selector: 'admin-article-detail',
  templateUrl: './article-detail.component.html',
  styleUrls: ['./article-detail.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush
 })
 @Input() articleId: string;
 selectedArticle : string; // create this new property and use it 

 constructor(private cd: ChangeDetectorRef) {}

 ngOnInit() { this.selectedArticle = this.articleId;  }

 ngDoCheck() {
  if (this.selectedArticle !== this.articleId) {
      this.selectedArticle = this.articleId;
      this.cd.markForCheck();
  }
 }

这篇关于Angular父子组件:在父单击上加载子组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆