角度2材料。在一个组件中工作的相同MdIcon在另一个组件中失败

时间:2016-08-12 12:37:53

标签: angular svg angular-material

我刚刚使用ng2 rc4material2 alpha6升级到ng2 rc5 material 2 alpha7-2。当我使用<md-icon>之前的代码时会弹出一个新错误。

我看不到完整的错误文本,因为我得到Observable_1.Observable.throw is not a function错误(应用程序崩溃),堆栈跟踪中的顶行是:

MdIconRegistry.prototype.getNamedSvgIcon
    @angular2-material/icon/icon-registry.js:180:16
MdIcon.prototype.ngOnChanges
    @angular2-material/icon/icon.js:107:17

如果我console.log() icon-registry.js @ line 180 ic_lightbulb_outline_24px material 2 alpha 7-2 ...<svg viewBox="..." id="ic_lightbulb_outline_24px"><path d="..."/></svg>... ,我会看到图标的ID <md-icon svgIcon="ic_lightbulb_outline_24px"></md-icon> 。这个图标出现在我的svg精灵中,但在我今天升级到AppComponent之前它已正确显示。这是svg sprite中的部分:

this._iconRegistry.addSvgIconSet('src/icons/sprite.defs.svg');

模板:

MdIconModule

在我的主AppModule我有

<md-icon>

我还将AppComponent导入主HomeComponent

是什么令人费解的
  • 同一个精灵文件中的相同图标适用于其他组件和
  • 这在升级前有效!

另外两条信息:

  • 此问题仅影响延迟加载的模块
  • 如果在应用启动时加载的组件的模板上使用LazyLoadedComponent,则相同的模板组件可以正常工作,但如果在模板上使用此错误,则会失败并显示此错误一个懒惰的组件

I've built a Plunkr证明了这个问题。您会注意到急切加载的组件(MdIconRegistry.prototype.getNamedSvgIcon /@angular2-material/icon/icon-registry.js:180:16 MdIcon.prototype.ngOnChanges /@angular2-material/icon/icon.js:107:17 anonymous/_View_UserProfileComponent6.prototype.detectChangesInternal@UserProfileComponent.ngfactory.js:1318:29 AppView</AppView.prototype.detectChanges /@angular/core//bundles/core.umd.js:12586:13 AppView</AppView.prototype.detectContentChildrenChanges /@angular/core//bundles/core.umd.js:12604:17 anonymous/_View_UserProfileComponent1.prototype.detectChangesInternal@UserProfileComponent.ngfactory.js:294:3 AppView</AppView.prototype.detectChanges /@angular/core//bundles/core.umd.js:12586:13 AppView</AppView.prototype.detectContentChildrenChanges /@angular/core//bundles/core.umd.js:12604:17 anonymous/_View_UserProfileComponent0.prototype.detectChangesInternal@UserProfileComponent.ngfactory.js:37:3 AppView</AppView.prototype.detectChanges /@angular/core//bundles/core.umd.js:12586:13 AppView</AppView.prototype.detectViewChildrenChanges /@angular/core//bundles/core.umd.js:12612:17 anonymous/_View_UserProfileComponent_Host0.prototype.detectChangesInternal@UserProfileComponent.ngfactory.js:28:3 AppView</AppView.prototype.detectChanges /@angular/core//bundles/core.umd.js:12586:13 AppView</AppView.prototype.detectContentChildrenChanges /@angular/core//bundles/core.umd.js:12604:17 AppView</AppView.prototype.detectChangesInternal /@angular/core//bundles/core.umd.js:12596:13 AppView</AppView.prototype.detectChanges /@angular/core//bundles/core.umd.js:12586:13 AppView</AppView.prototype.detectViewChildrenChanges /@angular/core//bundles/core.umd.js:12612:17 AppView</AppView.prototype.detectChangesInternal /@angular/core//bundles/core.umd.js:12597:13 AppView</AppView.prototype.detectChanges /@angular/core//bundles/core.umd.js:12586:13 AppView</AppView.prototype.detectContentChildrenChanges /@angular/core//bundles/core.umd.js:12604:17 anonymous/_View_AppComponent0.prototype.detectChangesInternal@AppComponent.ngfactory.js:445:3 AppView</AppView.prototype.detectChanges /@angular/core//bundles/core.umd.js:12586:13 AppView</AppView.prototype.detectViewChildrenChanges /@angular/core//bundles/core.umd.js:12612:17 anonymous/_View_AppComponent_Host0.prototype.detectChangesInternal@AppComponent.ngfactory.js:30:3 AppView</AppView.prototype.detectChanges /@angular/core//bundles/core.umd.js:12586:13 ViewRef_</ViewRef_.prototype.detectChanges /@angular/core//bundles/core.umd.js:10804:58 ApplicationRef_</ApplicationRef_.prototype.tick/< /@angular/core//bundles/core.umd.js:10191:79 ApplicationRef_</ApplicationRef_.prototype.tick /@angular/core//bundles/core.umd.js:10191:17 ApplicationRef_/<.next/< /@angular/core//bundles/core.umd.js:10095:103 Zone</ZoneDelegate</ZoneDelegate.prototype.invoke /zone.js/dist/zone.js:323:20 NgZoneImpl/this.inner<.onInvoke /@angular/core//bundles/core.umd.js:9245:36 Zone</ZoneDelegate</ZoneDelegate.prototype.invoke /zone.js/dist/zone.js:322:20 Zone</Zone</Zone.prototype.run /zone.js/dist/zone.js:216:25 NgZoneImpl</NgZoneImpl.prototype.runInner /@angular/core//bundles/core.umd.js:9276:64 NgZone</NgZone.prototype.run /@angular/core//bundles/core.umd.js:9505:55 ApplicationRef_/<.next /@angular/core//bundles/core.umd.js:10095:73 EventEmitter</EventEmitter.prototype.subscribe/schedulerFn< /@angular/core//bundles/core.umd.js:9168:58 SafeSubscriber.prototype.__tryOrUnsub /rxjs/Subscriber.js:225:13 SafeSubscriber.prototype.next /rxjs/Subscriber.js:174:17 Subscriber.prototype._next /rxjs/Subscriber.js:124:9 Subscriber.prototype.next /rxjs/Subscriber.js:88:13 Subject.prototype._finalNext /rxjs/Subject.js:128:13 Subject.prototype._next /rxjs/Subject.js:120:13 Subject.prototype.next /rxjs/Subject.js:77:9 EventEmitter</EventEmitter.prototype.emit /@angular/core//bundles/core.umd.js:9156:58 NgZone</NgZone.prototype._checkStable /@angular/core//bundles/core.umd.js:9415:25 NgZone/this._zoneImpl<.onLeave /@angular/core//bundles/core.umd.js:9387:21 NgZoneImpl/this.inner<.onInvokeTask /@angular/core//bundles/core.umd.js:9239:29 Zone</ZoneDelegate</ZoneDelegate.prototype.invokeTask /zone.js/dist/zone.js:355:24 Zone</Zone</Zone.prototype.runTask /zone.js/dist/zone.js:256:29 ZoneTask/this.invoke /zone.js/dist/zone.js:423:29 和{{1}})能够显示图标。但是,{{1}}不能。

以下是完整的堆栈跟踪:

{{1}}

有什么想法吗?

(交叉发布on github

1 个答案:

答案 0 :(得分:1)

(这是my post here的复制品,因为这两个问题实际上是相同的)

我发现因为MdIconModule本身在MdIconRegistry数组中有providers服务,每次另一个模块导入它时,都会提供一个新的服务实例。因此,在引导时加载并且属于同一AppModule的所有组件共享此服务的相同实例。但是,稍后加载的组件(通过延迟加载)具有不同的服务实例,因此无法看到在引导时注册的图标。

使用help from James,我使用了根本不使用MdIconModule的特制模块的解决方法,而是单独声明MdIcon类。然后,我单独提供MdIconRegistry服务,并仅提供给根AppComponent。结果是,应用程序范围内只有一个服务实例,并且在引导时注册的图标随处可用。

修改后的MdIconFixedModule

@NgModule({
    imports: [CommonModule, HttpModule],
    declarations: [MdIcon],
    exports: [MdIcon],
    providers: [],//leave empty to avoid multiple instances of MdIconRegistry
})
export class MdIconFixedModule {
    static forRoot() {
        return {
            ngModule: MdIconFixedModule,
            //will be available only to whoever calls .forRoot()
            providers: [MdIconRegistry] 
        };
    }
}

只需使用图标的模块可以导入MdIconFixedModule,因为它不包含MdIconRegistryAppModule还需要注册包含该服务的图标导入MdIconFixedModule.forRoot()

此实施的详细信息can be seen here.

ng-Material Modules的这个限制被设置为fixed with the alpha 8 release