我有一个带有属性的服务,我想引用该属性并在多个组件中进行更改。我可以通过将其分配给组件中的属性直接在组件中直接引用它,还是应该订阅一个可观察对象?我尝试了两种方式,当我在组件中对其进行修改时,两种方式似乎都改变了服务中的属性。
account.service.ts
export class AccountService {
constructor(private http: HttpClient) { }
testAccount: Account = {
domain_name: "fortestaccoutnpage2",
account_number: "fortestaccoutnpage2",
bill_timing: "anniversary",
}
getAccount(): Observable<Account> {
return of(this.testAccount);
}
}
account.component.ts
export class AccountComponent implements OnInit {
constructor(private _accountService: AccountService) { }
changeAccountNumber() {
this.account.account_number = "changed"
}
account: Account = this._accountService.testAccount;
grabAccount(): void {
this._accountService.getAccount()
.subscribe(account => this.account = account);
}
ngOnInit() {
//this.grabAccount();
}
}
在上面的示例中,我基本上在组件中拥有account
,引用服务中的testAccount
,并且changeAccountNumber
方法有效。我评论了让account
订阅可观察对象的方法,但是当我这样做时,它也可以正常工作。一种方法比另一种更好?还是都很好?
答案 0 :(得分:3)
最好订阅而不是直接从服务中引用。
订阅的优点在于,只有在调用observable时才会触发调用。因此,在这种情况下,这并不重要,因为您只是在使用测试对象。但是,如果您是从服务器拨打电话,则无法确定何时返回数据。因此,如果您在数据返回之前单击该按钮,则事情可能会发生。
此外,当前除了将帐户分配给媒体资源外,您什么也不做。哪个有效但是,如果稍后您想做其他事情,例如安装一个加载微调器,并在获取数据时将其关闭。您肯定需要利用可观察的东西。
编辑: 另外,更改组件本身内部的帐户可能不是一个好习惯。那肯定会起作用,但是如果您走那条路线,可能会导致一些令人困惑的错误,并使测试变得更加困难。最好集中进行更改。我建议向服务中添加一个方法changeAccountNumber(newNumber),该服务将使用更改后的帐户值推出一个新的可观察项。有点花哨,但它更具可测试性,我认为它更易于维护。
答案 1 :(得分:0)
grabAccount(): void {
this._accountService.getAccount()
.subscribe(account => this.account = account);
}
在这里,您将account
(即_accountService.testAccount
)的值分配给this.account
。
因此this.account
和_accountService.testAccount
是对内存中同一对象的引用。改变一个总是会影响另一个。
为避免这种情况,您可以在将对象分配给this.account
这是执行此操作的简单方法:
grabAccount(): void {
this._accountService.getAccount()
.subscribe(account => this.account = JSON.parse(JSON.stringify(account)));
}
或者为避免代码重复,您可以在服务中进行克隆
getAccount(): Observable<Account> {
return of(JSON.parse(JSON.stringify(this.testAccount)));
}
如果您有更复杂的对象(例如,具有Date值),则此克隆方法将不起作用
答案 2 :(得分:0)
使用Rxjs中的行为主体实现,声明您的服务并安装行为主体,在创建另一个变量asObserver之后,您必须在目标组件中使用行为主体实现的下一个方法,以将最新的更改发送给行为服务中的主题,以后您可以订阅U想要该信息的任何组件
和这个 http://reactivex.io/rxjs/manual/overview.html
尝试一些事情,等我可以更好地帮助您