Ionic 3 动态模板 URL

Posted

技术标签:

【中文标题】Ionic 3 动态模板 URL【英文标题】:Ionic 3 Dynamic Template URL 【发布时间】:2018-03-25 12:44:19 【问题描述】:

我有一个应用程序,我正在用 ionic 重新开发,大约一年前我在 ionic-v1 中做过。我有多种模板类型可供用户选择,我想制作一个动态组件,它根据用户配置值加载其 templateURL。因此,就加载组件和获取正确的模板而言,一切正常,除了当我运行应用程序时,它会给出模板错误,就好像它不知道 ngModel 是一个角度属性一样。 这是我所拥有的:

import  Compiler, Component, AfterViewInit, OnInit, Injector, ViewChild, NgModule, NgModuleRef, ViewContainerRef  from '@angular/core';
import  NavController  from 'ionic-angular';

import  SomeService  from '../../app/services/app.services';

@Component(
    template: `<ng-container #dynamicvc></ng-container>`
)
export class DynamicHome implements OnInit 
    @ViewChild('dynamicvc',  read: ViewContainerRef ) container;
    ehi: any;
    sponsorGroups: any[];
    baseUrl: string;
    selectedSegment: string;

    constructor(private compiler: Compiler, private injector: Injector, private moduleRef: NgModuleRef<any>, private someSvc: SomeService, private navCtrl: NavController) 
        let vm = this;

        vm.selectedSegment = 'home';
    

    ngAfterViewInit() 
        let vm = this;

        const MaterialCardsSpookyHomeComponent = Component( templateUrl: './materialcardsspooky/materialcardsspooky-home.html' )(class MaterialCardsSpookyHomeComponent  );
        const MaterialCardsSpookyHomeModule = NgModule( declarations: [MaterialCardsSpookyHomeComponent])(class MaterialCardsSpookyHomeModule  );

        let moduleToUse = null;
        switch (vm.someSvc.template.toLowerCase()) 
            case 'materialcardsspooky':
                moduleToUse = MaterialCardsSpookyHomeModule;
                break;
        

        if (moduleToUse) 
            vm.compiler.compileModuleAndAllComponentsAsync(moduleToUse).then((factories) => 
                const f = factories.componentFactories[0];
                const cmpRef = f.create(vm.injector, [], null, vm.moduleRef);
                cmpRef.instance.ehi = vm.ehi;
                cmpRef.instance.sponsorGroups = vm.sponsorGroups;
                cmpRef.instance.baseUrl = vm.baseUrl;
                cmpRef.instance.selectedSegment = vm.selectedSegment;
                vm.container.insert(cmpRef.hostView);
            );
        
    

    ngOnInit() 
        let vm = this;

    

这是我的模板:

<ion-header>
  <ion-toolbar no-border-top no-border-bottom>
    <ion-segment [(ngModel)]="selectedSegment">
      <ion-segment-button value="home" no-border-bottom>
        <ion-icon name="home"></ion-icon>
      </ion-segment-button>
    </ion-segment>
  </ion-toolbar>
</ion-header>
<ion-content>
  <div [ngSwitch]="selectedSegment">
    <div *ngSwitchCase="'home'">
        ...
    </div>
  </div>
</ion-content>

这是我在 Chrome 开发工具中的错误:

无法绑定到“ngModel”,因为它不是“ion-segment”的已知属性。

    如果“ion-segment”是一个 Angular 组件并且它具有“ngModel”输入,则验证它是该模块的一部分。 如果“ion-segment”是 Web 组件,则将“CUSTOM_ELEMENTS_SCHEMA”添加到该组件的“@NgModule.schemas”以禁止显示此消息。 要允许任何属性将“NO_ERRORS_SCHEMA”添加到该组件的“@NgModule.schemas”。 ("

任何想法如何或即使我可以做到这一点?此外,使用带有默认构建脚本的 VS2017 和标准 Ionic 模板,即 webpack。

【问题讨论】:

我不确定这是否可能,但您可以尝试将其添加到您的 NgModule:imports: [ IonicPageModule.forChild(MaterialCardsSpookyHomeComponent) ] 不错!谢谢!这肯定是在正确的轨道上。这让我克服了尝试使用像 ngModel 这样的角度模块的错误,但现在我收到了关于使用我在模板中使用的自定义组件的错误。它说它不认识它,所以试图弄清楚如何让那个也能正常工作...... 很好,很高兴能为您提供一点帮助。如果自定义组件在另一个模块中声明,则还需要在模块的导入数组中;如果尚未在另一个模块中声明,则在声明数组中。 是的,这就是我现在迷路的地方。我把它放在导入中并得到这个错误:错误:模块'MaterialCardsSpookyHomeModule'导入的意外指令'ImageSliderComponent'。请添加 @NgModule 注释。所以我把它改成了声明,然后我得到“已经导入的错误”。因此,仅出于测试目的,我将其从 app.module 中取出,然后它告诉我它无法识别自定义属性。 哈哈!这是一个不同的组件,我从模块中删除了其他组件的组件。感谢您的帮助,我很感激。如果这是唯一的问题,我会通知您,以便您可以将建议更改为答案,我可以将其标记为答案。 【参考方案1】:

要让 Angular 识别 ionics 自定义组件,NgModule 的导入数组中需要以下内容:

imports: [ IonicPageModule.forChild(MaterialCardsSpookyHomeComponent) ]

此外,如果模块中某处使用的每个自定义组件已经在另一个模块中声明和导出,则需要在 imports 数组中;如果尚未在另一个模块中声明,则在 declarations 数组中。

【讨论】:

以上是关于Ionic 3 动态模板 URL的主要内容,如果未能解决你的问题,请参考以下文章

ionic 向路由中的templateUrl(模板页)传值

如何在Ionic 2应用程序中提取和重用导航栏模板和逻辑?

Angular.js 指令动态模板URL

带有可变 django 模板的动态 URL

Angular.js 组件动态模板URL

Django模板--反向解析