Angular2 - 使用服务

时间:2018-01-27 20:01:54

标签: angular typescript angular2-services angular2-components

我正在尝试使用通用共享服务在组件之间共享数据。这是服务。

@Injectable()
export class JobService {
    public jobType=null;
    public examples=[];
}

这是我的第一个组成部分。组件中的完整代码太长,所以我刚刚添加了...来表示代码的其余部分,但在此组件中,服务的jobTypeexamples变量是集。

@Component({
            selector: 'app-job',
            templateUrl: './job.component.html'
})
export class JobComponent implements OnInit {

          constructor(private jobService: JobService, private authService: AuthService, private router: Router) {
            }
    ...

}

,第二个组件是

@Component({
    selector: 'app-preview',
    template:'./preview.component.html'
})
export class PreviewComponent implements OnInit {

    jobType;
    examples;

    constructor(private jobService: JobService) {
    }  
    ngOnInit() {

        this.jobType=this.jobService.jobType;
        this.examples=this.jobService.examples;
    }

}

因此,我们的想法是,它应该能够获取jobType内服务中设置的examplesJobComponent变量。

服务本身在模块文件

中提供
@NgModule({
    declarations: [
        JobComponent,
        JobListComponent,
        JobDetailsComponent,
        PreviewComponent
    ],
    imports: [
        CommonModule,
        FormsModule,
        RouterModule,
        TabsModule
    ],
    providers: [JobService]
})
export class JobModule {

}

我的理解是,这意味着JobService只被实例化一次并在组件之间共享。

问题出现在JobComponent的html模板中。它包含一个路由器链接,用于在新选项卡中打开PreviewComponent,即

<a target="_blank" routerLink="/preview">Preview</a>

打开此链接时,JobService中的变量已在JobComponent中设置(我检查过这是真的)。 /preview路由与PreviewComponent相关联。当新窗口打开时 并且PreviewComponents读取了JobService个变量,但未设置这些变量会让我相信PreviewComponent创建了JobService的全新实例。但是,根据 Angular2 - Share data between components using services 如果JobService仅在模块文件中提供一次,则不应发生这种情况。谁能告诉我为什么JobService似乎没有在这两个组件中共享?

2 个答案:

答案 0 :(得分:2)

这是因为您在新窗口中打开了该页面。 JobService的状态未被保留。一种可能的解决方案是使用url查询参数将JobService状态传递给预览组件,并在新页面中重建服务,例如,导航到/preview?jobType=something&examples=are,comma,separated,list或保存状态。浏览器(本地存储,cookie,等等)并在页面初始化时读取它

答案 1 :(得分:1)

要保存共享资源的状态,您应该使用BehaviorSubject s。

@Injectable()
export class JobService {
    public jobType$: BehaviorSubject<any> = new BehaviorSubject('');
    public examples$: Behavior Subject<any[]> = new BehaviorSubject([]);
    public jobTypes = null;
    public examples = [];

    setJobType(jobType) {
        this.jobTypes = jobType;
        this.jobType$.next(this.jobTypes);
    }
    //set the same way for examples
}

然后在每个组件中。

@Component({
            selector: 'app-job',
            templateUrl: './job.component.html'
})
export class JobComponent implements OnInit {

  constructor(private jobService: JobService, private authService: AuthService, private router: Router) {}

  //somewhere like ngOnInit subscribe to jobType$ and or examples$

  //on some event or trigger of the ui call the setJobType method with changes.
}


@Component({
    selector: 'app-preview',
    template:'./preview.component.html'
})
export class PreviewComponent implements OnInit {

    jobType;
    examples;

    constructor(private jobService: JobService) {
    }  
    ngOnInit() {
        this.jobService.jobType$.subscribe(result => this.jobType = result);
        this.jobService.examples$.subscribe(result => this.examples = result);
    }
}