Angular 视图未更新,正在从一个组件调用方法到另一个组件

Angular view not updating, calling method from one component to another

我正在尝试从另一个组件调用一个组件,我正在调用该组件的一个方法,该方法被调用没有任何问题,但是该组件的视图没有刷新,下面是一个演示代码来展示我正在尝试做什么。

myFirstComponent.component.ts

ngOnInit() {
        this.secondComponent = new SecondComponent();
        this.secondComponent.showValues(5)
}

秒-component.component.ts

ngOnInit() {
       this.value = 10;    
       this.showValues(this.value)     
}

showValues(value: any) {
        this.newValue = value;
        console.log('This is console value' + this.newValue)
} 

在我的HTML,

New Value is {{newValue}}

第一次加载组件时的输出将是

New Value is 10
 //in console it will be This is console value 10

从第一个组件调用 showValues 时的输出

New Value is 10
// in console it will be, This is console value 5

所以变量值得到了更新,但它没有反映在 UI 上,我的第二个组件永远不会被刷新,这是否是一个很好的工作实践,或者是否有任何其他方式可以我能做到吗? 谢谢。

在同级组件之间传递数据或调用方法

在组件之间传递数据时,我发现 RxJS 的“BehaviorSubject”非常有用。

您也可以使用常规 RxJS Subject 通过服务共享数据,但这就是我更喜欢 BehaviorSubject 的原因。

  1. 它将始终 return 订阅的当前值 - 无需调用 onNext()。
  2. 它有一个 getValue() 函数来提取最后一个值作为原始数据。
  3. 它确保组件始终接收到最新数据。
  4. 您可以使用 asObservable() 从行为主题中获取可观察值 行为主体方法。

例子

在服务中,我们将创建一个私有的 BehaviorSubject 来保存消息的当前值。我们定义一个 currentMessage 变量来处理这个数据流作为一个将被其他组件使用的可观察对象。最后,我们创建调用 BehaviorSubject 上的 next 以更改其值的函数。

父组件、子组件和兄弟组件都接受相同的处理。我们在组件中注入 DataService,然后订阅 currentMessage observable 并将其值设置为等于消息变量。

现在,如果我们在这些组件中的任何一个中创建一个函数来更改消息的值。更新后的值会自动广播到所有其他组件。

shared.service.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class SharedService {

  private eventSource = new BehaviorSubject<string>("default message");
  eventSubject = this.eventSource.asObservable();

  constructor() { }

  emitEvent(value: string) {
    this.eventSource.next(value)
  }

}

sibling.component.ts

import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";

@Component({
  selector: 'app-sibling1',
  template: `
     {{message}}
   `,
   styleUrls: ['./parent.component.css']
})
export class SiblingComponent1 implements OnInit {

  message: string;

  constructor(private data: DataService) { }

  ngOnInit() {
    this.data.eventSubject.subscribe(value =>  this.showValues(value));
  }
}

sibling.component.ts

import { Component, OnInit } from '@angular/core';
import { SharedService } from "../shared.service";

@Component({
  selector: 'app-sibling2',
  template: `
    {{message}}
    <button (click)="emitEvent()">New Message</button>
  `,
  styleUrls: ['./sibling2.component.css']
})
export class SiblingComponent2 implements OnInit {

  message: string;

  constructor(private service: SharedService) { }

// emit value in oninit
  ngOnInit() {
   this.service.emitEvent("Hello from Sibling-1");
  }

// emit value on event
  emitEvent() {
    this.service.emitEvent("Hello from Sibling");
  }   
}

Why use Service ?

Angular 将组件与服务区分开来,以增加模块化和可重用性。 and It's Good Practice to Delegate complex component logic to services

From Angular Style Guide
Do limit logic in a component to only that required for the view. All other logic should be delegated to services.

Do move reusable logic to services and keep components simple and focused on their intended purpose.

Why? Logic may be reused by multiple components when placed within a service and exposed via a function.

Why? Logic in a service can more easily be isolated in a unit test, while the calling logic in the component can be easily mocked.

Why? Removes dependencies and hides implementation details from the component.

Why? Keeps the component slim, trim, and focused.

使用 Angular 中的服务还可以确保您不违反 DRY and SRP 软件开发原则,对于您的场景,最好的解决方案是使用一项服务