在控制器中公开服务属性的正确方法是什么?

时间:2016-11-14 16:30:02

标签: angularjs typescript

想象一下,我有一个控制器 ctrlA 。它有一个 serviceB 作为依赖。 该服务具有 propertyC 属性。我使用Anguler和Typescript。

在UI中,控制器的控制器我想根据该属性的值显示和隐藏一些html。

我可以:

  1. 将服务设为公共变量,并将其设置为:< ... ng-if =“serviceB.propertyC”>
  2. 在控制器中创建一个属性:

    public get exposedPropertyC(){    return this.serviceB.PropertyC;    }
    
  3. 访问该属性,如:< ... ng-if =“exposedPropertyC”>

    这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

我不会说正确,但一致。它们都可以正常工作,然而,由于每个组件的责任之间缺乏一致性(它可能也有测试问题),事情会开始变得有问题。

您应该通过控制器公开属性。它将保持其责任,因为它是充满活力的。而且,通过这样做,您的服务也将保持其责任。

  

正如@LoremIpsum在评论中所说的那样,另一个问题是"你的HTML没有达到太过分的东西"

此问题有几种情况。考虑class MyController声明的控制器。

直接访问属性

public exposedPropertyC: number;

constructor(private serviceB: ServiceB){
    this.serviceB = serviceB;
    this.exposedPropertyC = this.serviceB.PropertyC;
}

Assync aquired property

public exposedPropertyC: number;

constructor(private serviceB: ServiceB){
    this.serviceB = serviceB;
    this.serviceB.getPropertyC().then((propertyC) => {
        this.exposedPropertyC = propertyC;
    });
}

观察者模式

根据你的情况,有点矫枉过正,但观察者模式大多是一种最佳和奇特的解决方案。

以下代码是此模式的简单实现。但是你可能会发现更强大的库使用这个模式和typescript(但你明白了)。

  

免责声明。观察者模式是我最喜欢的模式,即使它看起来有点过分,它更加灵活,兼容未来的优化变化以及如何从服务器检索数据,即它带来了很多积极的可维护性的东西,也可以防止因设计不佳而导致的未来麻烦 ; {D

interface ObservableCallBack<T> {
    (arg: T): void;
}

class Observable<T> {
    public yielded: T;
    public observers: ObservableCallBack<T>[];

    public subscribe(observableCallBack: ObservableCallBack<T>): void {
        this.observers.push(observableCallBack);
        if(this.yielded !== null) observableCallBack(this.yielded);
    }

    public notify(arg: T): void {
        this.yielded = arg;
        this.observers.forEach((observer) => {
            observer(arg);
        });
    }
}

class ServiceB {    
    public propertyC: Observable<number>;

    constructor(private http: IHttpService) {            
        this.propertyC = new Observable<number>();

        this.http.get('').then((res) => {
            this.propertyC.notify(res.data);
        });
    }
}

class MyController {    
    public propertyC: number;

    constructor(private serviceB: ServiceB) {
        this.serviceB.propertyC.subscribe((propertyC) => this.propertyC = propertyC);
    }
}