【问题标题】:Service does not work well with *ngIf in Angular2Angular2 中的 *ngIf 服务不能很好地工作
【发布时间】:2016-02-02 17:22:12
【问题描述】:

编辑:嗯,我应该更清楚。这是一个 angular2-meteor 项目。因为流星是反应性的,所以可能有其他方式。但是@lodewijk-bogaards 对于纯 Angular2 项目来说是一个很好的解决方案。

我正在使用 Angular 2 (TypeScript)。

我尝试使用ChatService 服务将值“12345”从App 传递给ChatDetailsComponent

如果布尔值showChatDetails 为真,那么在我第一次单击“显示”按钮时它会显示“12345”,效果很好。

问题是,如果布尔值showChatDetails 为假,那么在我第二次单击“显示”按钮后,它将显示“12345”。我不知道为什么我第二次点击它,这应该也是第一次。

(请不要切换到[隐藏],因为我这里需要*ngIf。)

// app.ts

import {Component, View} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {ChatService} from './chat.service';
import {ChatDetailsComponent} from './chat-details.component';

@Component({
    selector: 'app'
})
@View({
    directives: [ChatDetailsComponent],
    template: `
        <button (click)="showButton()">Show</button>
        <chat-details-component *ngIf="showChatDetails"></chat-details-component>
    `
})
class App {
    // Here if it is true, it works well. If it is false, the problem comes.
    showChatDetails:boolean = false;  

    constructor(private _chatService: ChatService) {}

    showButton() {
        this._chatService.setChatId("12345");
        this.showChatDetails = true;
    }
}

bootstrap(App, [ChatService]);

// chat-details.component.ts

import {Component, View} from 'angular2/core';
import {ChatService} from './chat.service';

@Component({
    selector: 'chat-details-component'
})
@View({
    template: `
        <div>ID: {{chatId}}</div>
    `
})
export class ChatDetailsComponent {
    chatId:string;

    constructor(private _chatService: ChatService){}

    ngOnInit() {
        this._chatService.getChatId().subscribe(id => this.chatId = id);
    }
}

// chat.service.ts

import {EventEmitter} from 'angular2/core';

export class ChatService {
    chatId: EventEmitter<string> = new EventEmitter();

    setChatId(id) {
        this.chatId.emit(id);
    }

    getChatId() {
        return this.chatId;
    }
}

【问题讨论】:

    标签: meteor typescript angular angular-meteor angular2-meteor


    【解决方案1】:

    对我来说,这似乎是一种竞争条件。如果ChatDetailsComponent 订阅ChatService 之后chatId 已经发出,它将不会收到它。这是很容易实现的,因为 Angular 会在 Rx 安排事件发射的同时安排组件的创建。

    我可以提出多种解决方案,但我建议您考虑使用 ReplaySubject 而不是 EventEmitter。

    【讨论】:

    • 谢谢,洛德维克!实际上它是一个 angular2-meteor 项目。由于流星是反应性的,我还没有看到任何带有 RxJS 项目的流星。所以我会等待一点时间等待其他答案。
    • 刚刚尝试使用 ReplaySubject,效果非常棒!这是正确的答案,解释也是正确的。
    • 其实 EventEmitter is 只是一个 RxJs Subject 而 Angular 2 需要 RxJs,所以我无法想象它不会出现在 angular2-meteor 中。
    • @LodewijkBogaards 是的,你说得对,我才意识到 EventEmitter 和 Rx 之间的关系。但是,我只在angular2/core.d.ts 中找到了 EventEmitter,但没有找到 Rx。所以我不能直接使用 Rx.abc 。我可能需要一些时间才能弄清楚。
    【解决方案2】:

    我不确定您的目标是按照您所说的方式完成任务,或者您是否灵活地完成任务。

    我认为将chatId 设置为ChatDetailsComponent@Input() 并让AppchatId 更改时创建组件的新实例的可能性要小得多。

    包含组件必须知道何时需要创建ChatDetailsComponent 的实例。让它通过所需的chatId irhgt 对我来说似乎是一种更好的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-12
      • 2013-12-22
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 2010-10-23
      • 2011-12-02
      • 1970-01-01
      相关资源
      最近更新 更多