(Angular 6)子函数是否应该返回它正在操作的对象?

问题描述 投票:1回答:3

我不是训练的开发者,所以很可能我的问题揭示了一些基本的误解。我试过搜索这个主题,但我真的不确定要找什么短语。 (这与范围有关吗?权限?)

我正在开发一个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.agescenario.value(在parentFunction内)的值反映childFunction内所做的变化,childFunction必须返回这些对象(并且parentFunction必须将其“子”和“场景”对象设置为等于childFunction返回的内容)。

但是,如果我在调用console.log之后立即对他们进行了childFunction,他们的价值实际上已经改变了。

由于某种原因,让childFunction回归“人”和“情景”仍然是可取的吗?

如果在其他地方存在类似的讨论,再次道歉。我很难找到它们,因为我不确定哪些术语甚至可以引用我所询问的主题。

javascript angular typescript angular-services
3个回答
2
投票

根据这个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);
    });

1
投票

我建议使用返回新对象的解决方案,因为在这种情况下,您可以轻松地将单元测试编写到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中不变性的文章,这些内容对此有很大帮助。


-1
投票

不需要,因为Person和Calculationscenario看起来像你的接口/类,它们已经具有参考访问权限,这意味着你可以直接从ParentFunction访问age和scenario.value。它的正确方法是做到这一点。没有伤害或没有编码标准细分。

© www.soinside.com 2019 - 2024. All rights reserved.