Angular服务中的数据持续跨项目
我是一个有抱负的FE开发人员,可以学习很多东西。以前,我们的系统中出现了一个错误,其中来自的数据将出现在另一个项目中。想象一下,查看动物A的数据,A Deer ,然后导航到动物B,A 狗,并在Animal B屏幕上的UI中看到有关鹿角大小的信息。
这种类型的错误的模式以及后续的修复程序是,Angular组件没有在其正确使用的服务中管理数据,并且必须重置它。
例如:
@Component
export class AnimalComponent implements OnInit, OnDestroy {
traitSummary: string;
constructor(animalTraitService: AnimalTraitService) {}
getAnimalTraitData(animalId: Number) {
this.animalTraitService.getData(animalId).pipe(
tap((traits) => {
this.animalTraitService.formattedData = formatDataForAnimalType(traits);
this.traitSummary = extractTraitSummary(traits);
}),
catchError(error => {
// this is the call we added to fix "antlers" from appearing on dog
// this.animalTraitService.formattedData = null;
return of(null);
})
).subscribe();
}
formatDataForAnimalType(traits: AnimalTraits): AnimalTraits {
var formattedData = _.cloneDeep(traits);
... apply some formatting logic
return formattedData;
}
...
}
简而言之,组件无法正确管理这些服务中的数据,并在注入新页面的组件中 对于服务,我们看到了旧的forsfortdata。
这是参考的服务:
@Injectable()
export class AnimalTraitService {
private _formattedData;
get formattedData() {
return this._formattedData;
}
set formattedData(value) {
this._formattedData = value;
}
getResults(id) {
return this.httpService.get(`localhost:888/baseapp/results`);
}
}
在上面的示例中,动物组件加载了某些事件触发的鹿的信息。然后,组件格式化特征数据并将其存储在服务中。在加载狗的信息后,动物维修服务仍然存储在其_FormattedData中,该信息随后出现在UI上,直到某个过程替代了它。
在错误处理程序中重置数据,例如在OnDestroy事件处理程序中,对于正确重置服务是必要的。
我已经观察到这个问题在我们的代码库中发生了两次,这让我担心。
主要是因为它依靠开发人员努力地意识到其服务中定义的数据,并且似乎依靠利用这些服务正确管理的组件。
在这两种情况下,都可以从UI观察到,但是如果用户以不太明显的方式在错误的上下文中可视化数据,则可能会产生可怕的结果。在使用注射服务时,在Java世界中,我们通过不使用服务中的类实例数据来避免此问题,因为它们可以实例化一次,并同时由多个Proccess重复使用。 Angular中是否可以使用类似的设计模式来防止这种情况发生?
I am an aspiring FE developer with a lot to learn. Previously, a bug emerged in our system where data from one project would appear in another. Imagine looking at data for Animal A, a deer, then navigating to Animal B, a dog, and seeing information about antler size from Animal A in the UI on Animal B's screen.
The pattern of this type of bug, and the subsequent fix, is that the Angular component is not managing the data in a service it uses properly and must reset it.
For example:
@Component
export class AnimalComponent implements OnInit, OnDestroy {
traitSummary: string;
constructor(animalTraitService: AnimalTraitService) {}
getAnimalTraitData(animalId: Number) {
this.animalTraitService.getData(animalId).pipe(
tap((traits) => {
this.animalTraitService.formattedData = formatDataForAnimalType(traits);
this.traitSummary = extractTraitSummary(traits);
}),
catchError(error => {
// this is the call we added to fix "antlers" from appearing on dog
// this.animalTraitService.formattedData = null;
return of(null);
})
).subscribe();
}
formatDataForAnimalType(traits: AnimalTraits): AnimalTraits {
var formattedData = _.cloneDeep(traits);
... apply some formatting logic
return formattedData;
}
...
}
In short, components are not managing data in these services properly and, upon injection into a component for a new page
for the service we see the old formattedData.
Here is the service for reference:
@Injectable()
export class AnimalTraitService {
private _formattedData;
get formattedData() {
return this._formattedData;
}
set formattedData(value) {
this._formattedData = value;
}
getResults(id) {
return this.httpService.get(`localhost:888/baseapp/results`);
}
}
In the above example AnimalComponent loads the info for Deer triggered by some event. The component then formats the trait data and stores it back in the service. Upon loading the information for Dog, the AnimalTraitService still has deer info stored in its _formattedData which subsequently appears on the UI until some process replaces it.
Resetting the data, in this case in an error handler, but also for example in an onDestroy event handler is necessary to properly reset the service.
I have observed this issue occur twice in our codebase and it worries me.
Mostly because it relies on the developer to be diligently aware of the data defined in their services and seems to rely on the components utilizing these services to manage it correctly.
In both cases it was observable from the UI but there could be a dire consequence if users are visualizing data in the wrong context in a less obvious way. In the Java world when working with injectable services we avoid this problem by not using class instance data inside of services since they can be instantiated once and reused by multiple proccesses concurrently. Are there similar design patterns in Angular one could use to prevent this from occurring?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论