Angular 2 使用主题时出现打字问题

Angular 2 typing issue when using subject

我在 Angular 中使用主题时遇到问题 2. 运行 应用程序时出现以下错误:

Type '{}' is not assignable to type 'UserDevice[]'.)

// 服务

export class UserDeviceLocalService {

    udSubject = new ReplaySubject();
    tmpUserDevices: UserDevice[] = [];

    constructor() {
    }

    createUserDevices(userDevice){
    this.tmpUserDevices.push(userDevice);

    // localStorage.setItem('userdevices', JSON.stringify(this.tmpUserDevices));
    this.udSubject.next(this.tmpUserDevices);
    }
 }

// 组件

export class UserDeviceMenuComponent implements OnInit {

userDevices: UserDevice[];

constructor(private userDeviceLocalService: UserDeviceLocalService) {
}

ngOnInit() {
    this.userDeviceLocalService.udSubject.subscribe(userDevices => this.userDevices = userDevices);
}

也许这条线需要改变

this.udSubject.next(userDevice);

this.udSubject.next(tmpUserDevices);

因为userDevice是一个对象,不是对象数组

createUserDevices(userDevice){
    this.tmpUserDevices.push(userDevice);
    this.udSubject.next(this.tmpUserDevices);
    }

另外:

export class UserDeviceLocalService {
    udSubject = new ReplaySubject<UserDevice[]>();
    ...
}

并确保在组件销毁时取消订阅可观察对象以避免内存泄漏。

export class UserDeviceMenuComponent implements OnInit {

userDevices: UserDevice[];
supscription: Subscription;

constructor(private userDeviceLocalService: UserDeviceLocalService) {
}

ngOnInit() {
    this.subscription = this.userDeviceLocalService.udSubject.subscribe(userDevices => this.userDevices = userDevices);
}

ngOnDestroy() {
 this.subscription.unsubscribe();   
}

或者使用 async 管道为您处理退订。

您应该在 declaring/instantiating 您的 Subject 字段时指定类型:

udSubject = new ReplaySubject<UserDevice[]>();

在您的示例中,您可能需要的是 new ReplaySubject<UserDevice[]>(1);,因此仅重播最后一个值。

在这种情况下,您也可以使用 BehaviorSubject 而不是 ReplaySubject 并消除 tmpUserDevices:

export class UserDeviceLocalService {

    udSubject = new BehaviorSubject<UserDevice[]>([]);

    createUserDevices(userDevice: UserDevice) {
        let devices = this.udSubject.value;

        // maybe clone array first?
        devices = devices.slice();

        devices.push(userDevice);

        // localStorage.setItem('userdevices', JSON.stringify(devices));
        this.udSubject.next(devices);
    }
}

别忘了 un-subscribe 订阅 ngOnDestroy()

本文解释了 TypeScript 类型系统的一些方面:

http://blog.angular-university.io/typescript-2-type-system-how-does-it-really-work-when-are-two-types-compatible-its-actually-quite-different-than-other-type-systems/