Conflicting components in Ionic 4: IonCard and Swi

2019-07-27 09:26发布

问题:

I am following this tutorial, and I'm facing some difficulties regarding the differences between Ionic3 and 4. I am using Ionic4, and when I do ionic serve everything compiles successfully, but when I go to the web browser the following error appears in the console:

Uncaught Error: Template parse errors:
More than one component matched on this element.
Make sure that only one component's selector can match a given element.
Conflicting components: IonCard,SwingCardComponent ("stackConfig" (throwoutleft)="voteUp(true)" (throwoutright)="voteUp(false)"
    id="card-stack">
    [ERROR ->]<ion-card #mycards1 swing-card *ngFor="let c of cards">
      <ion-item *ngIf="c.picture">

I want to know why can't I use ion-card and swing-card together and what should I use instead. My home.page.html file is the following:

    <ion-header>
      <ion-toolbar>
        <ion-title>
          Ionic Blank
        </ion-title>
      </ion-toolbar>
    </ion-header>

    <ion-content padding>
      <div swing-stack #myswing1 [stackConfig]="stackConfig" (throwoutleft)="voteUp(true)" (throwoutright)="voteUp(false)"
        id="card-stack">
        <ion-card #mycards1 swing-card *ngFor="let c of cards">
          <ion-item *ngIf="c.picture">
            <ion-avatar item-left>
              <img *ngIf="c.picture" [src]="c.picture.medium">
            </ion-avatar>
            <h2>{{ c.name.first }} {{ c.name.last}}</h2>
            <p>{{ c.email }}</p>
          </ion-item>

          <ion-card-content *ngIf="c.location">
            From: {{ c.location.city }}, {{ c.location.postcode }}<br>
            Phone: {{ c.phone }}
          </ion-card-content>

          <ion-row *ngIf="c.name">
            <ion-col>
              <button ion-button clear small icon-left color="primary" (click)="voteUp(true)">
                <ion-icon name="thumbs-up"></ion-icon>
                Yes
              </button>
            </ion-col>
            <ion-col>
              <button ion-button clear small icon-left color="primary" (click)="voteUp(false)">
                <ion-icon name="thumbs-down"></ion-icon>
                No
              </button>
            </ion-col>
          </ion-row>
        </ion-card>
      </div>
      <p style="text-align: center; width: 100%;">{{ recentCard }}</p>
    </ion-content>

My home.page.ts file is the following:


    import { Component, ViewChild, ViewChildren, QueryList } from '@angular/core';
    import { NavController } from '@ionic/angular';
    import { Http } from '@angular/http';
    import 'rxjs/Rx';

    import {
      StackConfig,
      Stack,
      Card,
      ThrowEvent,
      DragEvent,
      SwingStackComponent,
      SwingCardComponent
    } from 'angular2-swing';

    @Component({
      templateUrl: './home.page.html'
    })

    export class HomePage {
      @ViewChild('myswing1') swingStack: SwingStackComponent;
      @ViewChildren('mycards1') swingCards: QueryList<SwingCardComponent>;

      cards: Array<any>;
      stackConfig: StackConfig;
      recentCard: string = '';

      constructor(private http: Http) {
        this.stackConfig = {
          throwOutConfidence: (offsetX, offsetY, element) => {
            return Math.min(Math.abs(offsetX) / (element.offsetWidth / 2), 1);
          },
          transform: (element, x, y, r) => {
            this.onItemMove(element, x, y, r);
          },
          throwOutDistance: (d) => {
            return 800;
          }
        };
      }

      ngAfterViewInit() {
        // Either subscribe in controller or set in HTML
        this.swingStack.throwin.subscribe((event: DragEvent) => {
          event.target.style.background = '#ffffff';
        });

        this.cards = [{ email: '' }];
        this.addNewCards(1);
      }

      // Called whenever we drag an element
      onItemMove(element, x, y, r) {
        var color = '';
        var abs = Math.abs(x);
        let min = Math.trunc(Math.min(16 * 16 - abs, 16 * 16));
        let hexCode = this.decimalToHex(min, 2);

        if (x < 0) {
          color = '#FF' + hexCode + hexCode;
        } else {
          color = '#' + hexCode + 'FF' + hexCode;
        }

        element.style.background = color;
        element.style['transform'] = `translate3d(0, 0, 0) translate(${x}px, ${y}px) rotate(${r}deg)`;
      }

      // Connected through HTML
      voteUp(like: boolean) {
        let removedCard = this.cards.pop();
        this.addNewCards(1);
        if (like) {
          this.recentCard = 'You liked: ' + removedCard.email;
        } else {
          this.recentCard = 'You disliked: ' + removedCard.email;
        }
      }

      // Add new cards to our array
      addNewCards(count: number) {
        this.http.get('https://randomuser.me/api/?results=' + count)
          .map(data => data.json().results)
          .subscribe(result => {
            for (let val of result) {
              this.cards.push(val);
            }
          })
      }

      // http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript
      decimalToHex(d, padding) {
        var hex = Number(d).toString(16);
        padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;

        while (hex.length < padding) {
          hex = "0" + hex;
        }

        return hex;
      }

    }

and my home.module.ts is the following:

    import { NgModule } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { IonicModule } from '@ionic/angular';
    import { FormsModule } from '@angular/forms';
    import { RouterModule } from '@angular/router';

    import { HomePage } from './home.page';

    @NgModule({
      imports: [
        CommonModule,
        FormsModule,
        IonicModule,
        RouterModule.forChild([
          {
            path: '',
            component: HomePage
          }
        ])
      ],
      declarations: [HomePage]
    })
    export class HomePageModule {}

回答1:

You follow devdactic.com to make tinder card in IONIC Framework. It is old sample since IONIC 2, But your project is IONIC 4. I think there are many differences and strict rules. So the error is :

1- ion-card is ionic component

2- swing-card is SwingCardComponent

Both are trying to parse on single element and it would not allow in IONIC (may be in Angular also).

So i changed home.page.html as below:

<ion-header>
  <ion-toolbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content padding>
  <div swing-stack #myswing1 [stackConfig]="stackConfig" (throwoutleft)="voteUp(true)" (throwoutright)="voteUp(false)"
  id="card-stack">
  <div #mycards1 swing-card *ngFor="let c of cards">
      <ion-item *ngIf="c.picture">
          <ion-avatar item-left>
            <img *ngIf="c.picture" [src]="c.picture.medium">
          </ion-avatar>
          <h2>{{ c.name.first }} {{ c.name.last}}</h2>
          <p>{{ c.email }}</p>
      </ion-item>
      <ion-row *ngIf="c.location">
          From: {{ c.location.city }}, {{ c.location.postcode }}<br>
          Phone: {{ c.phone }}
        </ion-row>

        <ion-row *ngIf="c.name">
          <ion-col>
            <button ion-button clear small icon-left color="primary" (click)="voteUp(true)">
              <ion-icon name="thumbs-up"></ion-icon>
              Yes
            </button>
          </ion-col>
          <ion-col>
            <button ion-button clear small icon-left color="primary" (click)="voteUp(false)">
              <ion-icon name="thumbs-down"></ion-icon>
              No
            </button>
          </ion-col>
        </ion-row>
  </div>
</div>
<p style="text-align: center; width: 100%;">{{ recentCard }}</p>
</ion-content>

Screenshot:

Hope this could help you:) You can find updated source cod here devtactic-swipe