我不是训练的开发者,所以很可能我的问题揭示了一些基本的误解。我试过搜索这个主题,但我真的不确定要找什么短语。 (这与范围有关吗?权限?)
我正在开发一个Angular 6应用程序。在其中,我有一个具有从另一个服务调用函数的函数的服务。
嵌套函数操作已作为参数传递给它的对象上的各个字段。
像这样的东西:
parentFunction(person:Person, scenario:CalculationScenario){
person.age = 1
scenario.value = 0
this.otherService.childFunction(person, scenario)
console.log(person.age) //logs "2"
console.log(scenario.value) //logs "100"
}
而在其他服务:
childFunction(person:Person, scenario:CalculationScenario){
person.age = person.age + 1
scenario.value = scenario.value + 100
//Does not return anything
}
我曾经认为,为了使person.age
和scenario.value
(在parentFunction
内)的值反映childFunction
内所做的变化,childFunction
必须返回这些对象(并且parentFunction
必须将其“子”和“场景”对象设置为等于childFunction
返回的内容)。
但是,如果我在调用console.log
之后立即对他们进行了childFunction
,他们的价值实际上已经改变了。
由于某种原因,让childFunction
回归“人”和“情景”仍然是可取的吗?
如果在其他地方存在类似的讨论,再次道歉。我很难找到它们,因为我不确定哪些术语甚至可以引用我所询问的主题。
根据这个childFunction()
的使用情况,这可能是更好的选择。
服务方法返回值以提高其可重用性是个好主意。
看看这项服务的getHeroes()
方法:
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
import { MessageService } from './message.service';
@Injectable({
providedIn: 'root',
})
export class HeroService {
constructor(private messageService: MessageService) { }
getHeroes(): Observable<Hero[]> {
this.messageService.add('HeroService: fetched heroes');
return of(HEROES);
}
}
它不是更改服务中声明的变量的值,而是返回一些英雄。
这很有用,因为在某些组件中,我可以像getHeroes()
方法那样做:
import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';
@Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
heroes: Hero[];
constructor(private heroService: HeroService) { }
ngOnInit() {
this.getHeroes();
}
getHeroes(): void {
this.heroService.getHeroes()
.subscribe(heroes => this.heroes = heroes);
}
}
我可以通过更改getHeroes()
组件方法轻松自定义要在某些视图上使用的输出,而无需更改服务并确保任何组件都可以使用相同的getHeroes()
服务方法。
让服务方法返回某些东西的另一个好理由是更容易测试它们。
正如BalázsTakács所示,期望值可以非常简单地编写:
it('should return correct sum', () => {
expect(service.myMethod(1, 2))
.toEqual(3);
});
我建议使用返回新对象的解决方案,因为在这种情况下,您可以轻松地将单元测试编写到childFunction。
childFunction(person:Person,
scenario:CalculationScenario): [Person, CalculationScenario] {
person.age = person.age + 1
scenario.value = scenario.value + 100
return [person, scenario];
}
service.spec.ts
it('should return updated person and scenario in an array', () => {
const mockPerson = {age: 0};
const mockScenario = {value: 0};
const expectedReturnValue = [{age: 1}, {value: 100}];
expect(service.childFunction(mockPerson, mockScenairio))
.toEqual(expectedReturnValue);
});
此外,我建议你阅读有关javascript中不变性的文章,这些内容对此有很大帮助。
不需要,因为Person和Calculationscenario看起来像你的接口/类,它们已经具有参考访问权限,这意味着你可以直接从ParentFunction访问age和scenario.value。它的正确方法是做到这一点。没有伤害或没有编码标准细分。