想象一下,我有一个控制器 ctrlA 。它有一个 serviceB 作为依赖。 该服务具有 propertyC 属性。我使用Anguler和Typescript。
在UI中,控制器的控制器我想根据该属性的值显示和隐藏一些html。
我可以:
在控制器中创建一个属性:
public get exposedPropertyC(){ return this.serviceB.PropertyC; }
访问该属性,如:< ... ng-if =“exposedPropertyC”>
这样做的正确方法是什么?
答案 0 :(得分:1)
我不会说正确,但一致。它们都可以正常工作,然而,由于每个组件的责任之间缺乏一致性(它可能也有测试问题),事情会开始变得有问题。
您应该通过控制器公开属性。它将保持其责任,因为它是充满活力的。而且,通过这样做,您的服务也将保持其责任。
正如@LoremIpsum在评论中所说的那样,另一个问题是"你的HTML没有达到太过分的东西" 。
此问题有几种情况。考虑class MyController
声明的控制器。
public exposedPropertyC: number;
constructor(private serviceB: ServiceB){
this.serviceB = serviceB;
this.exposedPropertyC = this.serviceB.PropertyC;
}
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);
}
}