【问题标题】:How to update a child component in Angular when a function returns a new value?当函数返回新值时,如何更新 Angular 中的子组件?
【发布时间】:2021-06-25 19:36:26
【问题描述】:

有两个组成部分:ParentChild

parent.ts

class Parent {
    state = 0;
    ...
};

parent.html

<child [state]='state'> </child>

每当我在 Parent 中更新 state 时,更新都会反映在子组件中。

由于重构,我不得不从 Parent 中删除 state,而现在有了一个单例类:

class Application {
    private static getState();
    private static setState(state: number);
}

无论何时我拨打Application.setState(0),都不会再通知孩子。让子组件知道Application.getState() 现在将返回不同值的常用技术是什么?

【问题讨论】:

    标签: angular


    【解决方案1】:

    最好使用 Angular BehaviorSubject 服务并让组件订阅更改事件。我创建了一个简单的 Pokemon Api,它完全符合您的需求。很容易看到源代码中发生了什么。

    服务如下

    @Injectable()
    export class PokemonFilterService {
      private pokemonfilterStatus = new PokemonFilter();
      private pokemonFilterSource = new BehaviorSubject<PokemonFilter>(this.pokemonfilterStatus);
    
      // this updates the data from the component
      change(data: PokemonFilter) : void {
        this.pokemonFilterSource.next(data);
      }
    
      // this lets the subscribing component know the data has changed
      public filterDataHasChanged(): Observable<PokemonFilter> {
        return this.pokemonFilterSource.asObservable();
      }
    }
    

    pokemon-header 页面有这个代码

    @Component({
      selector: 'app-pokemon-header',
      templateUrl: './pokemon-header.component.html',
      styleUrls: ['./pokemon-header.component.scss']
    })
    export class PokemonHeaderComponent implements OnInit {
      typeList: Array<PokeTypes>;
      pokemonFilter: PokemonFilter;
    
      constructor(private route: ActivatedRoute, private pokemonFilterService: PokemonFilterService) { }
    
      ngOnInit(): void {
        // one api call - get the list once and pass it down
        // fyi the api call was cached by the resolver
        this.typeList = this.route.snapshot.data['typeList'].results as Array<PokeTypes>;
        this.typeList = this.typeList.sort((a, b) => (a.name > b.name) ? 1 : -1);
        // use this service to check if the filter values changes from detail component (reset)
        this.pokemonFilterService.filterDataHasChanged().subscribe((pokemonFilter: PokemonFilter) => {
          if (pokemonFilter) {
            this.pokemonFilter = pokemonFilter;
          }
        });
      }
    
      filterChanged(): void {
        this.pokemonFilterService.change(this.pokemonFilter)
      }
    }
      
    

    pokemon-detail 可以订阅和更改数据,并且会通知 header 组件。

    ngOnInit(): void {
    this.pagingOffset = 0;
    this.getPokemons(this.pagingOffset);
    
    // use this service to check if the filter values change (reset)
        this.pokemonFilterService.filterDataHasChanged().subscribe((pokemonFilter : PokemonFilter) => {
          if (pokemonFilter) {
            this.pokemonFilter = pokemonFilter;
          }
        });
      }
    

    总结

    在一个组件中更改数据,在另一个组件中订阅数据。组件可以不相关。

    在此处查看完整的源代码https://github.com/tfa7

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 2017-04-17
      • 2020-08-08
      相关资源
      最近更新 更多