将数据从Root(app)Componenet传递到路由组件

时间:2022-06-15 19:41:18

I want to make an API call by using a service call from within my app's root component (AppComponent). The resulting data needs to be displayed by one or more other (child) components that are controlled by the RouterModule. For example:

我想通过在我的应用程序的根组件(AppComponent)中使用服务调用来进行API调用。结果数据需要由一个或多个由RouterModule控制的其他(子)组件显示。例如:

export class AppComponent implements OnInit {

  constructor(private _myService: MyService){ }

  ngOnInit() {
    this._myService.getSomeData().subscribe(theData => {
      // theData needs to be displayed in ChildComponenet1 and / or ChildComponent2
    }, err => {
      console.log(err);
    });
  }
}

And my AppModule sets up routes using RouterModule:

我的AppModule使用RouterModule设置路由:

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    RouterModule.forRoot([
      { path: 'child-component-1', component: ChildComponent1 },
      { path: 'child-component-2', component: ChildComponent2 },
    ]),
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

I want to avoid making an http request every time a user navigates to a /child-component, which is why I need to load the data from the AppComponent. (Or maybe I am approaching this the wrong way?)

我希望每次用户导航到/ child-component时都避免发出http请求,这就是我需要从AppComponent加载数据的原因。 (或许我接近这个错误的方式?)

This must be a fairly common pattern, any advice on the best way to approach this would be helpful. Thank you!

这必须是一个相当普遍的模式,任何关于最佳方法的建议都会有所帮助。谢谢!

1 个解决方案

#1


1  

If this is just a simple app then what was suggested above to use a Service would be the best approach.

如果这只是一个简单的应用程序,那么上面建议使用服务将是最好的方法。

Another approach would be to have a look at state management using ngrx.

另一种方法是使用ngrx查看状态管理。

Here's an example of how you would do it (untested):

以下是您将如何操作的示例(未经测试):

// data.ts
import { ActionReducer, Action } from '@ngrx/store';

export const STOREDATA = 'STORE_DATA';

export function dataReducer(state: data = null, action: Action) {
    switch (action.type) {
        case STOREDATA:
            return action.payload;

        default:
            return state;
    }
}

In your app's main module, import those reducers and use the StoreModule.provideStore(reducers) function to provide them to Angular's injector:

在应用程序的主模块中,导入这些reducers并使用StoreModule.provideStore(reducers)函数将它们提供给Angular的注入器:

import { NgModule } from '@angular/core'
import { StoreModule } from '@ngrx/store';
import { dataReducer } from './data';

@NgModule({
    imports: [
        BrowserModule,
        StoreModule.provideStore({ data: dataReducer })
    ]
})
export class AppModule {}

Then in your AppComponent

然后在你的AppComponent中

import { Store } from '@ngrx/store';
import { STOREDATA } from './data';

interface AppState {
  data: any;
}

export class AppComponent implements OnInit {

   constructor(private _myService: MyService, private store: Store<AppState>){ }

   ngOnInit() {
       this._myService.getSomeData().subscribe(theData => {               
          this.store.dispatch({ type: STOREDATA, payload: theData });
       }, err => {
            console.log(err);
       });
   }
}

In you child component:

在您的子组件中:

import { Store } from '@ngrx/store';
import { STOREDATA } from './data';

interface AppState {
  data: any;
}

export class AppComponent implements OnInit {
   public data:any;

   constructor(private store: Store<AppState>){ 
       this.data = this.store.select('data');
   }
}

#1


1  

If this is just a simple app then what was suggested above to use a Service would be the best approach.

如果这只是一个简单的应用程序,那么上面建议使用服务将是最好的方法。

Another approach would be to have a look at state management using ngrx.

另一种方法是使用ngrx查看状态管理。

Here's an example of how you would do it (untested):

以下是您将如何操作的示例(未经测试):

// data.ts
import { ActionReducer, Action } from '@ngrx/store';

export const STOREDATA = 'STORE_DATA';

export function dataReducer(state: data = null, action: Action) {
    switch (action.type) {
        case STOREDATA:
            return action.payload;

        default:
            return state;
    }
}

In your app's main module, import those reducers and use the StoreModule.provideStore(reducers) function to provide them to Angular's injector:

在应用程序的主模块中,导入这些reducers并使用StoreModule.provideStore(reducers)函数将它们提供给Angular的注入器:

import { NgModule } from '@angular/core'
import { StoreModule } from '@ngrx/store';
import { dataReducer } from './data';

@NgModule({
    imports: [
        BrowserModule,
        StoreModule.provideStore({ data: dataReducer })
    ]
})
export class AppModule {}

Then in your AppComponent

然后在你的AppComponent中

import { Store } from '@ngrx/store';
import { STOREDATA } from './data';

interface AppState {
  data: any;
}

export class AppComponent implements OnInit {

   constructor(private _myService: MyService, private store: Store<AppState>){ }

   ngOnInit() {
       this._myService.getSomeData().subscribe(theData => {               
          this.store.dispatch({ type: STOREDATA, payload: theData });
       }, err => {
            console.log(err);
       });
   }
}

In you child component:

在您的子组件中:

import { Store } from '@ngrx/store';
import { STOREDATA } from './data';

interface AppState {
  data: any;
}

export class AppComponent implements OnInit {
   public data:any;

   constructor(private store: Store<AppState>){ 
       this.data = this.store.select('data');
   }
}