Angular 10 / Ioni c 5 - Передача входных данных из модального окна в родительский компонент - PullRequest
2 голосов
/ 13 июля 2020

Я пытаюсь передать данные из модального c ioni с <ion-input></ion-input>. Возвращенные данные затем отправляются в серверную часть firebase.

Более конкретно, я хочу, нажав кнопку, создать новую «рабочую область». У этого рабочего пространства есть заголовок, и при нажатии кнопки я хочу отобразить модальное окно с запросом заголовка для этого нового рабочего пространства. При следующем нажатии кнопки заголовок передается родительскому компоненту, который передает входные данные в новый документ рабочей области в firebase. Он также дает ему запись uID текущего пользователя.

Я новичок в angular и ioni c, поэтому я пробую двустороннюю привязку данных в модальном компоненте, но у меня нет достаточно твердый gr asp на смеси ionic / angular или ioni c модальном, чтобы иметь возможность обнаружить проблему.

В настоящее время это ошибка, которая отображается, когда модальная кнопка нажата:

Uncaught (in promise): Error: This constructor is not compatible with Angular Dependency Injection because its dependency at index 1 of the parameter list is invalid.
This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.

Есть интерфейс рабочего пространства, который я установил на любой:

export interface Workspace {
  id?: any;
  title?: any;
  description?: any;
  color?: "blue" | "red" | "yellow";
  priority?: any;
}

Вот родительский компонент .ts с опущенным ненужным кодом:

import { Component, OnInit, OnDestroy } from "@angular/core";
import { Workspace } from "../models/workspace.model";
import { Subscription } from "rxjs";
import { WorkspaceService } from "src/app/services/workspace.service";
// ADD THE MODAL
import { ModalController } from "@ionic/angular";
import { WorkspaceModalComponent } from "../modals/workspace-modal.component";

@Component({
  selector: "app-workspaces",
  templateUrl: "./workspaces.component.html",
  styleUrls: ["./workspaces.component.scss"],
})
export class WorkspacesComponent implements OnInit, OnDestroy {
  // HANDLE WORKSPACE SUBSCRIPTION (Some code here not used) 
  workspace: Workspace;
  workspaces: Workspace[];
  sub: Subscription;

  constructor(
    public workspaceService: WorkspaceService,
    public modalController: ModalController
  ) {}

  // GET ALL WORKSPACES AND POPULATE THE WORKSPACES ARRAY
  ngOnInit() {
    this.sub = this.workspaceService
      .getUserWorkspaces()
      .subscribe((workspaces) => {
        this.workspaces = workspaces;
      });
  }

  /**
   * PRESENT THE MODAL FOR CREATING A NEW WORKSPACE
   * RETURN OF AN ASYNC FUNCTION HAS TO BE A PROMISE
   */
  async openWorkspaceModal() {
    const workspaceListModal = await this.modalController.create({
      component: WorkspaceModalComponent,
      // because this is a new workspace, there is no data being passed to the modal component
      componentProps: {},
    });
    workspaceListModal.onDidDismiss().then((data) => {
      if (data) {
        this.workspaceService.createWorkspace({
          title: data,
        });
      }
    });
    return await workspaceListModal.present();
  }
}

Родитель html:

<div class="workspaceGrid" style="padding-right: 30px;">
  <!-- [workspace]="workspace" passes the data down to the child component via an input property *ngFor="let workspace of workspaces" -->
  <app-workspace
    *ngFor="let workspace of workspaces"
    [workspace]="workspace"
  ></app-workspace>
  <ion-button (click)="openWorkspaceModal()">
    Open Modal
  </ion-button>
</div>

Вот служба настраиваемой рабочей области .ts, помогающая создать новую рабочую область в базе данных с идентификатором пользователя и данными, собранными из модального (заголовок prop):

import { Injectable } from "@angular/core";
import { AngularFireAuth } from "@angular/fire/auth";
import { AngularFirestore } from "@angular/fire/firestore";
import * as firebase from "firebase/app";
import { switchMap, map } from "rxjs/operators";
import { Workspace } from "../home/models/workspace.model";

@Injectable({
  providedIn: "root",
})
export class WorkspaceService {
  constructor(private afAuth: AngularFireAuth, private db: AngularFirestore) {}

  /**
   *
   * @param data
   * CREATES A WORKSPACE IN THE DATABASE BASED ON THE CURRENTLY LOGGED IN USER
   */
  async createWorkspace(data: Workspace) {
    const user = await this.afAuth.currentUser;
    return this.db.collection("workspaces").add({
      ...data,
      // automatically sets the UID property of the workspace here
      uid: user.uid,
    });
  }
}

Модальный компонент .ts и модальный html:

import { Component, Inject } from "@angular/core";
import { ModalController } from "@ionic/angular";
import { WorkspacesComponent } from "../workspaces/workspaces.component";
import { Workspace } from "../models/workspace.model";

@Component({
  selector: "app-workspace-modal",
  templateUrl: "./workspace-modal.component.html",
  styles: [],
})
export class WorkspaceModalComponent {
  constructor(public modalController: ModalController, public data: any) {}

  /**
   * CLOSE THE MODAL ON CLICK
   */
  async closeWorkspaceModal() {
    await this.modalController.dismiss();
  }
}
<ion-header color="primary" mode="ios">
  <ion-toolbar>
    <ion-title>New Workspace</ion-title>
    <ion-buttons slot="end">
      <ion-button (click)="closeWorkspaceModal()">
        <ion-icon slot="icon-only" name="close"></ion-icon>
      </ion-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content padding>
  <ion-item>
    <ion-input
      placeholder="Enter a title for the workspace"
      [(ngModel)]="data.title"
    >
    </ion-input>
  </ion-item>
  <!-- HANDLE SUBMISSION OF THE CONTENT -->
  <ion-button [data]="data.title" (click)="closeWorkspaceModal()"
    >Create Workspace</ion-button
  >
</ion-content>

Спасибо за любую помощь, которую вы могли предложить!

1 Ответ

0 голосов
/ 13 июля 2020

Проблема в конструкторе WorkspaceModalComponent, вы объявляете переменную public data: any. Angular Инжектор зависимостей анализирует тип переменных в конструкторе и пытается назначить правильный экземпляр в соответствии с типом. В этом случае типом является any, поэтому Angular не может понять, какую зависимость внедрять. Вместо этого вы должны объявить эту переменную как член класса. Примерно так:

export class WorkspaceModalComponent {
  public data: any;

  constructor(public modalController: ModalController) {}

  /**
   * CLOSE THE MODAL ON CLICK
   */
  async closeWorkspaceModal() {
    await this.modalController.dismiss();
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...