Angular2 - 服务初始调用为空

时间:2017-04-12 15:08:32

标签: angular typescript observable

我有一个带有子路由的父组件。我要做的是在它们之间共享一个项目变量。项目值可以更改,当它更改时,我需要更新所有路由页面。我一直关注anuglar2 tutorial如何实现这一目标。但是,当我第一次安装调用我的observable时,我遇到了问题。当我第一次调用它时,该值不会显示,但是,当我更新它时,将显示该值。我无法弄清楚为什么项目变量最初没有值。任何人都知道这是为什么以及如何解决它?

父路线(可以设置和更新项目)

onSubmit(value: any, valid: any) {
    if (valid) {
        // http request to get project 
        this.ad.searchProject(value)
            .subscribe(
            response => {
                // If projet found set value in service 
                this.ad.setProject(response);
                // navigate to child rotue 
                this.router.navigate(['./project'], { relativeTo: this.route });
            },
            error => {
                console.log(error)
            },
            () => {
                console.log("Project Loaded");
            }
            );
    }
}

project service.ts

@Injectable()
export class ProjectService {
    public project: Project;
    // Observable string sources
    private projectSource = new Subject<Project>();
    // Observable string streams
    projectListener$ = this.projectSource.asObservable();
    constructor(private http: Http) {
    }
    searchProject(value: string): Observable<any> {
        return this.http.post('/controller/Project/SearchProject', { value: value }, { headers: headers })
            .map(response => response.json());
    }
    // Service message commands
    setProject(project: Project) {
        this.projectSource.next(project);
        console.log("call setProject"); 
    }
}

儿童路线

export class ChildComponent {
    project: Project = null;
    subscription: Subscription;
    constructor(private ad: ProjectService) {
        console.log("call child route"); 
        this.subscription = this.ad.projectListener$.subscribe(
            value => {
                // Called after second value is entered
                console.log("call subscription");
                console.log(value);
                this.project = value;
            });
    }
}

console.log

[HMR] connected
call parent route
Gravity_Project
setProject
Project Loaded
call child route
// done with first project entry 
Waves Project
call subscription
Object {id: 1001, typeID: 45004, studentID: 10000…}
call setProject
Project Loaded
// done with second project entry 

1 个答案:

答案 0 :(得分:1)

答案是行为主题(https://hassantariqblog.wordpress.com/2016/12/03/angular2-difference-between-a-behavior-subject-and-an-observable/

“行为主体是一种主体,主体是一种特殊的可观察类型,因此您可以像任何其他可观察者一样订阅消息。行为主体的独特特征是:

行为主题需要初始值,因为它必须始终返回订阅值,即使它没有收到next() 订阅后,它将返回主题的最后一个值。常规observable仅在收到onnext时触发 在任何时候,您都可以使用getValue()方法在不可观察的代码中检索主题的最后一个值。