为什么最好订阅服务主题而不是从功能中获取数据?

时间:2019-08-05 16:11:00

标签: angular service observable

我的角度聊天应用程序中有一个聊天消息列表。我从ChatMessagesService获得了带有消息的数据。在ChatViewComponent中,我在构造函数中注册了服务,然后从服务中获取了数据并将它们放到用于渲染消息的组件数组中。

服务具有两个功能,一个用于设置来自websoceket的传入新消息并将其推送到本地服务数组,第二个fn返回包含消息的本地(相同)数组。

我正在学习角度学习两个星期,在此期间,我正在制作自己的应用程序。我想知道,为什么在组件中我应该订阅服务中的可观察对象(正如我所观看的课程之一),如果我只使用servcie中的函数,该函数仅返回消息数组,以及此数组中的每个更改在服务中影响到我的聊天视图数组,而无需使用subsrcibe。

ChatViewComponent

@Component({
  selector: 'conpeek-chat-view',
  template: '
<div class="row conpeek_message_chat_row" *ngFor="let chatMessage of chatMessages"> ... </div>
'
  styleUrls: ['./chat-view.component.css']
})

export class ChatViewComponent implements AfterViewInit {
  constructor(private chatMessagesService: ChatMessagesService) {
    this.chatMessages = this.chatMessagesService.getMessages();
  }
}

ChatMessagesService

export class ChatMessagesService {

  constructor(public dialogMembersService:DialogMembersService) {
  }

  chatMessages = [];

  getMessages(){
    return this.chatMessages;
  }

  addMessage(chatMessage){
    this.chatMessages.push(chatMessage);
  }
}

chatMessages = [];作为主题与将使用此服务的所有组件(即使它不是可观察的对象)的所有更改都体现出来时,将其作为普通数组返回的区别是什么?

1 个答案:

答案 0 :(得分:2)

您是否听说过角度变化检测策略

Default策略每次在组件中传播事件(鼠标,单击,输入,XHR等)时都会检查视图。此策略不适用于复杂的应用程序,因为性能可能很糟糕。

一种替代方法是使用OnPush策略。仅当@Input已更改或您明确要求使用ChangeDetectorRef.detectChanges();检测更改时,此策略才会重新呈现视图

因此,如果您不想使用订阅获取新数据,Angular将不会意识到您所做的更改将不会更新视图。

我真的建议您对Observable感到满意,因为它是强制性用法。

在任何地方添加subscribe()都会使您感到疲倦,但这是因为这是一种不良做法。您应该使用Angular提供的async管道。
该管道将​​订阅您的数据,并在组件被销毁时取消订阅。

学习曲线很艰难,但是好处却是如此。

@Component({
  selector: 'conpeek-chat-view',
  template: '
<div class="row conpeek_message_chat_row" *ngFor="let chatMessage of chatMessages | async"> ... </div>
'
  styleUrls: ['./chat-view.component.css']
})

export class ChatViewComponent implements AfterViewInit {

  public chatMessages$: Observable<any[]>;
  constructor(private chatMessagesService: ChatMessagesService) {
    this.chatMessages$ = this.chatMessagesService.getMessages();
  }
}