RXJS Subject 的值未在重新加载页面上更新
RXJS Subject's value not updated on reloading page
我创建了一个服务,它有一个名为 selectedNode 的主题。当我直接 URL 加载页面时,我正在尝试更新主题的值。问题是 Subject 的值在传递 URL.
时尝试直接更新值时未更新
例如如果我打开 URL localhost:4200/blog/page/subpage
,它应该用值 page/subpage
更新 selectedNode。但是,事实并非如此。
我的代码如下:
blog.component.ts
import {Component, OnInit} from '@angular/core';
import {BlogService} from '../../services/blog.service';
import {Router} from '@angular/router';
@Component({
selector: 'app-blog',
templateUrl: './blog.component.html',
styleUrls: ['./blog.component.css']
})
export class BlogComponent implements OnInit {
constructor(private blogService: BlogService, private router: Router) {
}
ngOnInit() {
let routerURL = this.router.url;
routerURL = routerURL.replace('/blog/', '');
console.log(routerURL);
this.blogService.selectedNode.next(routerURL);
}
}
下面的代码没有更新 SelectedNode Subject。我在调试时检查过。尽管 routerURL 具有不同的值并且 this.blogService.selectedNode.next(routerURL);
也被调用,但该值未在 Subject 中更新。
我的blog.service.ts文件如下:
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs';
import {HttpClient} from '@angular/common/http';
@Injectable()
export class BlogService {
public selectedNode: Subject<string> = new Subject<string>();
public sideNavDisabled: Subject<boolean> = new Subject<boolean>();
constructor(private http: HttpClient) {
}
public getTreeNodes() {
return this.http.get('/assets/tree.json');
}
public getPageContent(page: string) {
return this.http.get('/assets/TreeStructure/' + page + '.html');
}
}
我的完整代码位于 https://github.com/vibhorgoyal18/atest-blog
并且可以在 https://stackblitz.com/github/vibhorgoyal18/atest-blog
上查看
首先,感谢您将您的代码放入 stackblitz。这帮助我更快地理解了问题!这就是我投票并回答你问题的原因。
The issue is that the value of Subject is not updated when I tries to update the value directly when passing the URL.
它实际上已更新。为了证明这一点,用下面的代码替换BlogComponent
的ngOnInit
方法:
const routerURL = this.router.url;
this.blogService.selectedNode.subscribe(console.log); // console.log is called here
this.blogService.selectedNode.next(routerURL);
问题是由于 在调用 Subject
的 next
方法之前未启动订阅 。订阅 Subject
的组件在调用此方法之前未实例化。
如果您想向 Subject
发出一个值并让它成为 未来 可观察对象将获得该值,而不管 Subject
订阅了什么在发射时,看看 ReplaySubject
虽然在查看ReplaySubject
s 之前,了解热和冷可观察对象之间的区别是很好的:主题是 'hot' 可观察对象,这意味着无论订阅什么,它们都会触发他们。相反,'cold' observables 的触发取决于订阅它们的内容。有关详细信息,请参阅 here。
我创建了一个服务,它有一个名为 selectedNode 的主题。当我直接 URL 加载页面时,我正在尝试更新主题的值。问题是 Subject 的值在传递 URL.
时尝试直接更新值时未更新例如如果我打开 URL localhost:4200/blog/page/subpage
,它应该用值 page/subpage
更新 selectedNode。但是,事实并非如此。
我的代码如下:
blog.component.ts
import {Component, OnInit} from '@angular/core';
import {BlogService} from '../../services/blog.service';
import {Router} from '@angular/router';
@Component({
selector: 'app-blog',
templateUrl: './blog.component.html',
styleUrls: ['./blog.component.css']
})
export class BlogComponent implements OnInit {
constructor(private blogService: BlogService, private router: Router) {
}
ngOnInit() {
let routerURL = this.router.url;
routerURL = routerURL.replace('/blog/', '');
console.log(routerURL);
this.blogService.selectedNode.next(routerURL);
}
}
下面的代码没有更新 SelectedNode Subject。我在调试时检查过。尽管 routerURL 具有不同的值并且 this.blogService.selectedNode.next(routerURL);
也被调用,但该值未在 Subject 中更新。
我的blog.service.ts文件如下:
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs';
import {HttpClient} from '@angular/common/http';
@Injectable()
export class BlogService {
public selectedNode: Subject<string> = new Subject<string>();
public sideNavDisabled: Subject<boolean> = new Subject<boolean>();
constructor(private http: HttpClient) {
}
public getTreeNodes() {
return this.http.get('/assets/tree.json');
}
public getPageContent(page: string) {
return this.http.get('/assets/TreeStructure/' + page + '.html');
}
}
我的完整代码位于 https://github.com/vibhorgoyal18/atest-blog 并且可以在 https://stackblitz.com/github/vibhorgoyal18/atest-blog
上查看首先,感谢您将您的代码放入 stackblitz。这帮助我更快地理解了问题!这就是我投票并回答你问题的原因。
The issue is that the value of Subject is not updated when I tries to update the value directly when passing the URL.
它实际上已更新。为了证明这一点,用下面的代码替换BlogComponent
的ngOnInit
方法:
const routerURL = this.router.url;
this.blogService.selectedNode.subscribe(console.log); // console.log is called here
this.blogService.selectedNode.next(routerURL);
问题是由于 在调用 Subject
的 next
方法之前未启动订阅 。订阅 Subject
的组件在调用此方法之前未实例化。
如果您想向 Subject
发出一个值并让它成为 未来 可观察对象将获得该值,而不管 Subject
订阅了什么在发射时,看看 ReplaySubject
虽然在查看ReplaySubject
s 之前,了解热和冷可观察对象之间的区别是很好的:主题是 'hot' 可观察对象,这意味着无论订阅什么,它们都会触发他们。相反,'cold' observables 的触发取决于订阅它们的内容。有关详细信息,请参阅 here。