【问题标题】:Angular - Submit form in one component to trigger action in seperate unrelated componentAngular - 在一个组件中提交表单以触发单独不相关组件中的操作
【发布时间】:2021-10-13 02:28:04
【问题描述】:

在这个问题之前我made this question。基本上,我试图做到这一点,因此当提交单独组件中的表单时,它会创建一个组件的新实例,其中传入的值来自该组件实例上显示的表单。这些组件是在我将数据添加到 app.component.ts 中的数组时创建的。

感谢一个答案,我现在确实可以使用它,但是现在我正在尝试使它在提交不同组件中的表单时创建这些组件。

当表单中的数据添加到 app.component.ts 中的数组时,它会创建这些组件实例之一,但我只希望在通过 ngSubmit 提交表单时发生这种情况一个单独的组件,即 add-status-box.component.ts

add-status-box.component.html:

<form [formGroup]="AddStatusBoxForm" (ngSubmit)='addStatusBox()'>

add-status-box.component.ts:

    export class AddStatusBoxComponent implements OnInit, OnDestroy 
    {
    
      message!: string;
      subscripton!: Subscription;
    
      constructor(private Form: FormBuilder, private data: StatusBoxService) { }
    
      AddStatusBoxForm = this.Form.group({
        name: ['']
      });
    
      ngOnInit(): void 
      {
        this.subscripton = this.data.currentMessage.subscribe(name => this.name = name)
      }
    
      ngOnDestroy(): void 
      {
        this.subscripton.unsubscribe();
      }

    addStatusBox()
    {
        this.data.changeMessage(this.AddStatusBoxForm.get('name')?.value);
        this.dialogRef.close();
    }
  }

app.component.ts:

export class AppComponent implements OnInit, OnDestroy
{

  name!: string;
  subscription!: Subscription;
  myNames: any[] = [];

  constructor(private data: StatusBoxService) {}

  ngOnInit(): void 
  {
    this.subscription = this.data.currentName.subscribe(name => this.name = name)
    this.myNames.push(this.name);
  }

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

status-box.service.ts

export class StatusBoxService 
{
  private messageSource = new BehaviorSubject('defaulty');
  currentMessage = this.messageSource.asObservable();
  
  changeMessage(message: string)
  {
    this.messageSource.next(message);
  }
}

当我调用 add-status-box.component.ts 中附加到表单 ngSubmit 的 addStatusBox() 时,名称字段输入被传递到通过changeMes​​sage函数的StatusBoxService。

然后在 app.component.tsngInit() 函数中,我们订阅 StatusBoxService 并从表单中检索传入的名称值。然后将其分配给 name 属性。

最后我们将该名称添加到 myNames 数组中,但是我希望仅当我在 add-status-box.component.ts 中提交相同的表单时才发生将项目添加到数组中的关键步骤强>。因为正如你所看到的,我在 oninit() 期间向这个数组添加了项目。

我做了find this,似乎 ngSubmit 是一个 EventEmitter。看起来你可以订阅 EventEmitters。所以我可以在 app.component.ts 中的 app-status-box.component.ts 中订阅 ngSubmit,这样我就只当 ngSubmit 发生时,将项目添加到数组中。

我不确定这是否正确,如果正确,我不确定我将如何实现它。我之前从 StatusBoxService 检索名称值时使用过 subscibe,所以也许我可以做一些类似的事情?

任何帮助将不胜感激。

【问题讨论】:

  • 您不能在subscribe 回调中移动this.myNames.push(this.name); 吗?这样,只有在 this.data.currentMessage 发出一个新值时才会调用它(我希望在提交表单时会发生这种情况)。
  • 另请注意,使用当前代码,您将在数组更新之前将this.name 推送到数组(subscribe 是异步的)。
  • 你能给我举个例子吗?我试过这个: this.subscription = this.data.currentMessage.subscribe(message => this.message = message, this.myConfigs.push(this.message));但它只是错误。
  • 另外,我将如何纠正 this.name 在更新之前传递给数组的异步问题?
  • this.data.currentMessage.subscribe(message =&gt; { this.message = message; this.myConfigs.push(this.message); });

标签: angular form-submit angular-components angular-event-emitter ng-submit


【解决方案1】:

为避免在 cmets 中进一步讨论,我尝试在回答中给您一些建议,尽管它可能不会详尽无遗。很难清楚地了解您当前的情况和您的要求(将一个工作示例放在一起会很有帮助)。

无论如何:

(1) 我不清楚您为什么要尝试使用动态组件。如果您的要求是为myNames 中的每个项目显示一个组件,只需使用ngFor

<app-status-box *ngFor="let item in myNames"></app-status-box>

(2) 花点时间对 Observables 的工作原理有一个初步的了解。您在ngOnInit 中订阅this.data.currentName 的事实并不意味着您的回调函数只被调用一次,正如您所想的那样。该函数(您在subscribe() 中编写的函数)每次this.data.currentName 发出一个新值时都会触发。只订阅一次。

(3) 由于StatusBoxService 上的这一行,您将在提交表单之前获得&lt;app-status-box&gt; 的初始呈现:

private messageSource = new BehaviorSubject('defaulty');

再次,花点时间阅读文档,了解 BehaviorSubject 的工作原理。订阅后,它将发出其当前值,并且由于您将'defaulty' 定义为初始值,因此这是您在AppComponent 中获得的第一个值,即使在提交表单之前也是如此。要解决此问题,您可以将 null 作为初始值并在回调中添加检查。

小例子:

    // status-box.service.ts
    private messageSource = new BehaviorSubject(null);
    
    // app.component.ts
    ngOnInit(): void 
      {
        this.subscription = this.data.currentName.subscribe(name => {
        if (name) {
           this.name = name;
          this.myNames.push(this.name);
        }    
    });
  }

【讨论】:

    猜你喜欢
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    • 2018-04-30
    • 2019-05-29
    • 1970-01-01
    • 2017-03-27
    相关资源
    最近更新 更多