Driver
Driver

Reputation: 164

Angular 2/Ionic 2, extend ionic component parse errors: More than one component matched on this element

Doubt

I developed an Ionic 2 application and I would like to create extensions for some components already deployed in Ionic 2.

Example

For example, I create ngModule and try to extends ionic item but retaining its functionality and interaction with other Ionic components. Make <extended-ion-item> work like <ion-item>, but change <extended-ion-item> template and add new functionality.

Link to the repository with reproduced problem: https://github.com/SonyStone/ionicExtend-issue

extended-item.ts

import { ChangeDetectionStrategy, Component, ElementRef, Renderer, Optional, ViewEncapsulation } from '@angular/core';

import { Config, Form, ItemReorder, Item } from 'ionic-angular';

import { CopyItem } from './copy-item';

@Component({
    selector: 'extended-ion-item',
    template:
    '<ng-content select="[item-left],ion-checkbox:not([item-right])"></ng-content>' +
    '<div class="item-inner">' +
    '<div class="input-wrapper">' +
    '<ng-content select="ion-label"></ng-content>' +
    '<ion-label *ngIf="_viewLabel">' +
    '<ng-content></ng-content>' +
    '</ion-label>' +
    '<ng-content select="ion-select,ion-input,ion-textarea,ion-datetime,ion-range,[item-content]"></ng-content>' +
    '</div>' +
    '<ng-content select="[item-right],ion-radio,ion-toggle"></ng-content>' +
    '<ion-reorder *ngIf="_shouldHaveReorder"></ion-reorder>' +
    '</div>' +
    '<div class="button-effect"></div>',
    host: {
        'class': 'item'
    },
    changeDetection: ChangeDetectionStrategy.OnPush,
    encapsulation: ViewEncapsulation.None,
})
export class ExtendedItem extends Item {
    constructor(
        form: Form,
        config: Config,
        elementRef: ElementRef,
        renderer: Renderer,
        @Optional() reorder: ItemReorder
    ) {
        super(form, config, elementRef, renderer, reorder);
    }
}

module.ts

import { NgModule } from '@angular/core';
import { IonicModule } from 'ionic-angular';
import { BrowserModule } from '@angular/platform-browser';

import { ExtendedItem } from './extended-item';
import { CopyItem } from './copy-item';


@NgModule({
    imports: [
        BrowserModule,
        IonicModule,
    ],
    exports: [
        ExtendedItem,
        CopyItem,
    ],
    declarations: [
        ExtendedItem,
        CopyItem,
    ],
})
export class IonicExtensionModule { }

Problem

But I got this error and really do not know how to solve it.

console

Unhandled Promise rejection: 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: Item,ExtendedItem ("

<ion-content padding>
    [ERROR ->]<ion-item>
            <ion-avatar item-left>
                <ion-icon name="logo-markdown" style="color: #412159" ></ion"): HomePage@7:1

Upvotes: 1

Views: 2584

Answers (1)

Driver
Driver

Reputation: 164

It's turned out the problem in ionic 2 npm module, where Item @Component metadata was stored in Item.decorators object, so when I extend Item, its metadata inherited too. So I create class TempItem extends Item, clear out metadata, and then class ExtendedItem extends TempItem, and it's working now!

import { ChangeDetectionStrategy, Component, ElementRef, Renderer, Optional, ViewEncapsulation } from '@angular/core';

import { Config, Form, ItemReorder, Item } from 'ionic-angular';

class TempItem extends Item {
    static decorators = undefined;
}

@Component({
    selector: 'extended-ion-item',
    templateUrl: './extended-item.html',
    host: {
        'class': 'item item-block'
    },
    changeDetection: ChangeDetectionStrategy.OnPush,
    encapsulation: ViewEncapsulation.None,
})
export class ExtendedItem extends TempItem {
    constructor(
        form: Form,
        config: Config,
        elementRef: ElementRef,
        renderer: Renderer,
        @Optional() reorder: ItemReorder
    ) {

        super(form, config, elementRef, renderer, reorder);
    }
}

Upvotes: 1

Related Questions