首页 > 解决方案 > 如何使用RouterHook保留角度飞镖组件的状态?

问题描述

我试图在 Angular Dart 中更改路由时保留组件的状态。我偶然发现了RouterHook 抽象类,它有一个名为canReuse的抽象函数。

添加组件以获取数据后,我想调用 API。然而,如果向前和向后导航到该组件,应用程序不应再次调用 API(状态保留)。最好讨论一下 AngularDart 应用程序的生命周期。

@Component(
  selector: 'blog-listing',
  templateUrl: 'blog_listing_component.html',
  styleUrls: [
    'package:angular_components/css/mdc_web/card/mdc-card.scss.css',
    'blog_listing_component.css',
  ],
  providers: [
    ClassProvider(BlogService),
  ],
  directives: [
    BlogDetailsComponent,
    coreDirectives,
    routerDirectives,
    FixedMaterialTabStripComponent,
    MaterialButtonComponent,
    MaterialIconComponent,
    MaterialSpinnerComponent,
  ],
)
class BlogListingComponent implements OnInit ,RouterHook{
 
  List<String> categories = ["Category 1","Category 2", "Category 3"];
  String currentCategory;
  int currentTabIndex;

  int skip;
  int limit;
  int blogCount;

  List<Blog> currentBlogsPerCategory;
  Blog currentBlog;

  final Router _router;
  final BlogService _blogService;

  BlogListingComponent(this._blogService, this._router);

  BaseState getBlogsState;

  bool get isLoading => getBlogsState is LoadingState;

  bool get isError => getBlogsState is ErrorState;

  @override
  void ngOnInit() async {
    currentCategory = categories[0];
    _blogService.getBlogsPerCategory(currentCategory);
    BlogService.blogsBloc.listen((state) {
      this.getBlogsState = state;
      if (state is GotBlogsByCategoryState) {
        currentBlogsPerCategory = state.blogs;
        currentBlogsPerCategory = state.blogs;
      }else if (state is GotMoreBlogsByCategoryState) {
        currentBlogsPerCategory.clear();
        currentBlogsPerCategory.addAll(state.blogs);
      }
    });
  }

  @override
  void ngOnDestroy() async {
    _blogService.dispose();
  }

  void onBeforeTabChange(TabChangeEvent event) {
    skip = 0;
    limit = 9;
    currentBlogsPerCategory.clear();
    currentTabIndex = event.newIndex;
    currentCategory = categories[event.newIndex];
    currentBlogsPerCategory = null;
    _blogService.getBlogsByCategory(categories[event.newIndex], skip, limit);
  }

  void onNextPagePressed(int page) {
    skip = (page-1) * 9;
    limit = skip + 9;
    _blogService.getMoreBlogsByCategory(currentCategory, skip, limit);
  }

  void onBlogDetailsPressed(Blog blog) {
    BlogService.currentBlog = blog;
    goToBlogDetails();
  }

  Future<NavigationResult> goToBlogDetails(){
    _router.navigate(RoutePaths.blogDetails.toUrl());
  }

  @override
  Future<bool> canActivate(Object componentInstance, RouterState oldState, RouterState newState) {
    // TODO: implement canActivate
    throw UnimplementedError();
  }

  @override
  Future<bool> canDeactivate(Object componentInstance, RouterState oldState, RouterState newState) {
    // TODO: implement canDeactivate
    throw UnimplementedError();
  }

  @override
  Future<bool> canNavigate() {
    // TODO: implement canNavigate
    throw UnimplementedError();
  }

  @override
  Future<bool> canReuse(Object componentInstance, RouterState oldState, RouterState newState) async{
    return true;
  }

  @override
  Future<NavigationParams> navigationParams(String path, NavigationParams params) {
    // TODO: implement navigationParams
    throw UnimplementedError();
  }

  @override
  Future<String> navigationPath(String path, NavigationParams params) {
    // TODO: implement navigationPath
    throw UnimplementedError();
  }
}

标签: dartlifecycleangular-dartstate-managementangular-dart-routing

解决方案


RouterHook不应由组件路由实现,应注入以供Router.

class MyHook implements RouterHook {}

@GenerateInjector([
  routerProviders,
  Provider(RouterHook, useClass: MyHook)
])
const providers = ng.providers$Injector;

runApp(MyAppComponent, providers);

但是,对于您的用例,使用CanReusemixin 更简单。

class BlogListingComponent with CanReuse implements OnInit {}

或者

class BlogListingComponent implements OnInit, CanReuse {
  @override
  Future<bool> canReuse(RouterState oldState, RouterState newState) async {
    return true;
  }
}

推荐阅读