简体   繁体   English

输入更改值时,角度组件不更新

[英]Angular component not updating when input changes value

So I have a component that takes in a value from an object.所以我有一个从对象中获取值的组件。 I have the outer div subscribed to a behavior subject.我有外部 div 订阅了一个行为主题。 When I update the behavior subjects value using next() the title of the container div updates but the inner component refuses to re-render.当我使用next()更新行为主题值时,容器 div 的标题会更新,但内部组件拒绝重新渲染。 Am I doing something wrong here?我在这里做错了吗?

Here is the behavior subject in my controller, this is called in the ngOnInit method and the update method that is called on button click in the html:这是我的控制器中的行为主题,它在ngOnInit方法和在 html 中单击按钮时调用的更新方法中调用:

ngOnInit() {
  this.selectedRole$.next({ name: 'Current Permissions', permissions: this.getUserPermissions()
}

showRoleDetails(role: any): void {
  this.selectedRole$.next(role);
}

here is the parent component html this is where I am using async to subscribe to the behavior subject.这是父组件 html 这是我使用异步订阅行为主题的地方。 the selectedRole.name updates perfectly but the inner c-permissions-display does not re-render: selectedRole.name更新完美,但内部c-permissions-display不会重新呈现:

<div *ngIf="selectedRole$ | async as selectedRole" class="col-8">
  <h5 class="font-weight-medium mb-0 text-gray-500 mb-4 permissions-title">{{ selectedRole.name }}</h5>
  <div class="section-container">
    <c-permissions-display [permissions]="selectedRole.permissions"></c-permissions-display>
  </div>
</div>

here is the c-permissions-display component:这是c-permissions-display组件:

import { Component, OnInit, Input } from '@angular/core';
import { UtilityService } from 'src/app/canopy-common/services/utility.service';

@Component({
  selector: 'c-permissions-display',
  templateUrl: './permissions-display.component.html',
  styleUrls: ['./permissions-display.component.scss']
})
export class PermissionsDisplayComponent implements OnInit {

  @Input() permissions: any[];
  formattedPermissions: any[];

  constructor(
    private util: UtilityService
  ) { }

  ngOnInit() {
    this.formattedPermissions = this.formatPermissionsArray();
  }

  private formatPermissionsArray(): any {
    return stuff
  }
}

if I place a console log in the ngOnInit it calls once when the page loads but never again after calling next() on the behavior subject.如果我将控制台日志放在ngOnInit它会在页面加载时调用一次,但在对行为主题调用next()后不再调用。 I know I can get this to work if I implement OnChanges and then the ngOnChanges() method but I should not have to do that it should update and re-render on its own if its input changes value.我知道如果我实现OnChangesngOnChanges()方法,我可以ngOnChanges()但我不应该这样做,如果它的输入更改值,它应该自行更新和重新呈现。 Unless they changed that in angular 9除非他们在角度 9 中改变了

I think i remember it is because selectedRole.permission is an array and angular can't know if a value inside this array is changing or not.我想我记得是因为 selectedRole.permission 是一个数组,而 angular 不知道这个数组中的值是否正在改变。

So to make the array refresh too, you must overwrite the permission array with a new one.因此,要使阵列也刷新,您必须用新阵列覆盖权限阵列。 Something like selectedRole.permission = [new permission array ].类似于 selectedRole.permission = [新权限数组]。

This way angular should be able to detect the change and refresh the view.这样 angular 应该能够检测到变化并刷新视图。

Instead of passing value to child component.而不是将值传递给子组件。 you can pass observable to child component and subscribe inside child component so that whenver value changes in parent component child component get notified.您可以将 observable 传递给子组件并在子组件内订阅,以便在父组件子组件中的值发生变化时得到通知。

Try this尝试这个

parent.component.html父组件.html

<div *ngIf="selectedRole$ | async as selectedRole" class="col-8">
  <h5 class="font-weight-medium mb-0 text-gray-500 mb-4 permissions-title">{{ selectedRole.name }}</h5>
  <div class="section-container">
    <c-permissions-display [permissions]="selectedRole$"></c-permissions-display>
  </div>
</div>

child.component.ts子组件.ts

export class PermissionsDisplayComponent implements OnInit {

   @Input() permission = new BehaviorSubject(null);
   formattedPermissions: any[];

  constructor(
    private util: UtilityService
  ) { }

  ngOnInit() {
    this.permission.subscribe(permission=>{
        this.formattedPermissions = this.formatPermissionsArray();
    })

  }

  private formatPermissionsArray(): any {
    return stuff
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM