无法在angular2中通过服务传递数据 [英] Cannot pass data with service in angular2

查看:49
本文介绍了无法在angular2中通过服务传递数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

PS:

当我与同事交谈时,他们告诉我让罗尔斯(Role)正确 一次请求,如果未通过身份验证则拒绝,否则返回 数据到前端.但是,我被困在使用Angular2的Guard中.

When I talk to my colleague, they told me to get Role's right with once request, if it is not authenticated then reject, else return the data to frond-end. But, I got stuck in use Angular2's Guard.

应用程序这样做:

  1. 访问我的路由,并Guard阻止它,Guard向服务器发送请求以检查其身份验证.
  2. 请求server,当服务器返回statue:truedata:[somedatas]时,使用模块的dataService设置数据,并为canActivate解析true.
  3. constructor中初始化目标组件,使用dataService获取元数据.
  1. Access my routes, and Guard prevent it, the Guard send a request to server to check its auth.
  2. Request the server, when server return statue:trueanddata:[somedatas] then set data with module's dataService, and resolve true for canActivate.
  3. Init the target component, in constructor, use dataService to get the meta data.

但是,我无法将数据从我的Guard传递到Service.我在同一模块中提供它们.这是我的代码:

But, I failed to pass the data from my Guard to Service. I provide them in same module. Here's my code:

Module.ts:

Module.ts:

@NgModule({
  declarations: [
    DocsComponent,
    DocsListComponent, // this is the component I will access
    BarButtonsComponent
  ],
  imports: [
    CommonModule,
    DocsRouting,
    // ShareModule
  ],
  providers:[
    DocsGuard,
    DocsDataService // here I provide my dataService that I mentioned before
  ],
  exports: [DocsComponent],
})

路线:

const DOCS_ROUTES:Routes = [
  {path:'',redirectTo:'doclist',pathMatch:'full'},
  {path:'',component:DocsComponent,children:[
    {path:'doclist', component: DocsListComponent}
  ], canActivate:[DocsGuard] } // use `Guard` to prevent it.
];

我的dataService.ts:

My dataService.ts:

  private doclist:Doclist[] ; // this

  getData(){
    return this.doclist; 
  }

  setData(obj){
    this.doclist = obj;
  }

  getDocAuth(): Observable<any>{
    let options = new RequestOptions({
      withCredentials:true
    });
    // ...using get request
    return this.http.get(this.docUrl,options)
    // ...and calling .json() on the response to return data
      .map((res:Response) =>res.json())
      //...errors if any
      .catch((error:any) => {
        console.log(error)
      })
  }

Guard.ts:

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean>{
    let subject = new Subject<boolean>();
    let that = this;
    this.docsDataService.getDocAuth().subscribe(
      res=>{
        if(res.status){
          // Here I want to pass data to my component, I failed.
          that.docsDataService.setData(res.data); 
          subject.next(true);
        }else{
          subject.next(false);
        }
        console.log("next: returning true");
      },
      err => {
        console.log(err);
        subject.next(false);
      }
    );
    return subject.asObservable().first();
  }

谢谢.

======================补充2017-02-17 17:34 ================= ======

======================supplement 2017-02-17 17:34======================

Appmodule路由:

Appmodule routes:

const APP_ROUTERS:Routes = [
  { path:'',component:JwLoginComponent},
  { path:'main',loadChildren:'app/main/main.module#MainModule'},
  { path:'**', component: PageNotFoundComponent }
];

主要路线:

const MAIN_ROUTES : Routes = [
  {path:'main',component:MainComponent,canActivate:[DataGuard]},
  {path:'share',loadChildren:'app/common/share.module#ShareModule'}
];

共享路线:

const SHARE_ROUTES:Routes = [
  {path:'',redirectTo:'docs',pathMatch:'full'},
  {path:'',component: ShareComponent,children:[
    { path:'docs',loadChildren:'app/docs/docs.module#DocsModule'},  
    // Question here: cannot get data from service set in DocsModule, but in MainModule or AppModule as providers.
    { path:'mic',loadChildren:'app/mic/mic.module#MicModule'},
    { path:'user-manage',loadChildren:'app/user-manage/user-manage.module#UserManageModule'},
    { path:'settings',loadChildren:'app/settings/settings.module#SettingsModule'},
    { path:'logs',loadChildren:'app/logs/logs.module#LogsModule'}
  ]},

];

我发现我在MainModule或AppModule中提供了DocService,我可以从@mxii代码中获取数据.但是,当我将此服务设置为DocsModule或ShareModule时,我无法获取数据.

I found I provide the DocService in MainModule or AppModule, I can got data from @mxii code. But, when I set this service into DocsModule or ShareModule, I cannot got data.

推荐答案

该演示应帮助:

@Injectable()
export class DataService {
  public data = new BehaviorSubject<any>(null);

  public setData(data: any) {
    this.data.next(data);
  }
}

@Injectable()
export class AuthService {
  public validate(user, pass): Observable<any> {
    return Observable.of({ test: 'data' }).delay(123);
  }
}

@Injectable()
export class DocsGuard implements CanActivate {

  constructor(private _authService: AuthService, private _dataService: DataService) {}

  canActivate() {
    return this._authService.validate('user', 'pass').map(data => {
      console.log('GUARD: auth data:', data);

      // .. do something ..

      if (!data || data.anyThing === 'anyValue') {
        console.log('GUARD: auth WRONG');
        return false; // not authenticated !
      }

      console.log('GUARD: auth OKAY, set data..');

      this._dataService.setData(data);

      return true;
    })
    .catch(err => {
      console.log(err);
      return Observable.of(false); // protect route !
    });
  }
}

@Component({
  selector: 'my-comp',
  template: `
    {{ _data | async | json }}
  `,
})
export class DocsListComponent {

  private _data: BehaviorSubject<any>;

  constructor(private _dataService: DataService) { }

  ngOnInit() {
    this._data = this._dataService.data;
    this._data.subscribe(data => {
      console.log('DocsListComponent: something changed', data);
    });
  }
}

实时演示: https://plnkr.co/edit/PGsTD3Ma9yDidhxEgot3?p=preview

更新

仅应一次包含您的服务!

您必须provide将您的服务添加到最高"的NgModule.

You have to provide your Service to the "highest" NgModule.

否则,每个NgModule都会创建一个新的Service实例.

Otherwise every NgModule will create a NEW instance of your Service..

如果对一个NgModule仅provided,则为单例!

If it's only provided to one NgModule, its a singleton!

也许您必须像RouterModule一样创建forRootforChild之类的功能.

Maybe you have to create functions like forRoot and forChild like the RouterModule does.

这篇关于无法在angular2中通过服务传递数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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