繁体   English   中英

如何在 Storybook 中使用 observable 或 subject 更新 Angular 组件?

[英]How can I update Angular component with observable or subject in Storybook?

我想使用一个主题来更新我的 Angular 组件,但是当我在 Storybook 中调用subject.next(false)时它不起作用。 组件实例的属性已更新但不适用于 canvas 面板。

我有一个这样的加载组件

@Component({
    selector: 'app-loading',
    templateUrl: './loading.component.html'
})
export class LoadingComponent implements OnInit, OnDestory {
    // control the loading icon show or not
    public state: boolean = true;
    private subscription: Subscription = null;

    constructor(private loadingSerivce: LoadingService) {}

    ngOnInit(): void {
        this.subscription = this.loadingService.state.subscribe(state => {
            this.updateState(state);
            console.log(this.state);
        });
    }

    ngOnDestroy(): void {
        if (this.subscription) {
            this.subscription.unsubscribe();
        }
    }

    updateState(state: boolean): void {
        this.state = state;
    }
}

和这样的加载服务

@Injectable({
    providedIn: 'root'
})
export class LoadingService {
    public state: Subject<boolean> = new Subject<boolean>();
}

和这样的加载故事

@Injectable({
    prividedIn: 'root'
})
class MockLoadingService extends LoadingService {
    static instance: MockLoadingService = null;

    constructor() {
        super();

        if (!MockLoadingService.instance) {
            MockLoadingService.instance = this;
        }

        return MockLoadingService.instance;
    } 
}

@Component({
    selector: 'app-loading',
    templateUrl: './loading.component.html',
})
class MockLoadingComponent extends LoadingComponent {
    constructor(private mockLoadingService: MockLoadingService) {
        super(mockLoadingService);
    }
}

export default {
    title: 'Loading',
    component: MockLoadingComponent,
    decorators: [
        moduleMetadata({
            declarations: [MockLoadingComponent],
            providers: [MockLoadingService],
        }),
    ],
} as Meta;

export const Loading: Story = props => ({ props });

Loading.play = async () => {
    await new Promise(resolve => {
        setTimeout(() => {
            MockLoadingService.instance.state.next(false);
            resolve(null);
        }, 2000);
    });
};

问题是:在npm run storybook之后,我可以得到 state is false ,但是 canvas 面板中的加载图标仍然显示。 那么如何在 Storybook 中使用 observable 或 subject 更新 Angular 组件呢?


补充说明 loading.component.html

<div *ngIf="state" class="loading" id="loading">
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="25 25 50 50" class="circular">
        <circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
    </svg>
</div>

它是这样工作的

ngOnInit(): void {
    this.subscription = this.loadingService.state.subscribe(state => {
        this.updateState(state);
        console.log(this.state);
    });

    setTimeout(() => {
        this.loadingService.state.next(false);
    }, 1000);
}

只是在故事书游戏中不起作用 function

您的订阅订阅了错误的服务? 您的组件加载LoadingService的实例并订阅该实例

this.loadingService.state.subscribe

但是next一条语句是在MockLoadingService的实例上触发的吗?

MockLoadingService.instance.state.next(false);

尽管一个扩展了另一个,但这两个不是相同的服务吗?

所以解决方案,要么在组件构造函数中使用MockLoadingService ,要么在LoadingService class 而不是MockLoadingService class 上触发next调用?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM