ngFor 中的 Angular2 组件抛出错误(viewFactory 不是函数)

Posted

技术标签:

【中文标题】ngFor 中的 Angular2 组件抛出错误(viewFactory 不是函数)【英文标题】:Angular2 Component inside ngFor throws Error (viewFactory is not a function) 【发布时间】:2016-04-22 09:29:24 【问题描述】:

我在 Angular 2 应用程序(测试版 1)中有一个 ComponentB。在我将它放在 ComponentA 的 ngFor 循环中之前,它工作得非常好。我收到以下相当神秘的错误:

例外:TypeError:viewFactory_ComponentB0 不是 [ComponentA@1:23 中的数字]BrowserDomAdapter.logError @ angular2.dev.js:22690BrowserDomAdapter.logGroup @ angular2.dev.js:22701ExceptionHandler.call @ angular2.dev 中的函数。 js:1163(匿名函数)@angular2.dev.js:12416NgZone._notifyOnError@angular2.dev.js:13324collection_1.StringMapWrapper.merge.onError@angular2.dev.js:13228run@angular2-polyfills.js:141(匿名函数) @ angular2.dev.js:13247NgZone.run @ angular2.dev.js:13209(匿名函数) @ angular2.dev.js:12499schedulerFn @ angular2.dev.js:12742tryCatcher @ Rx.js:31Subscriber.next @ Rx. js:9500Subject._next@Rx.js:9999Subject.next@Rx.js:9963EventEmitter.emit@angular2.dev.js:12723(匿名函数)@angular2.dev.js:13140run@angular2-polyfills.js:138NgZone。 _notifyOnTurnDone @ angular2.dev.js:13139(匿名函数)@ angular2.dev.js:13254zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305 angular2.dev.js:22690 原始异常:TypeError: viewFactory_ComponentB0 不是函数BrowserDomAdapter.logError @ angular2.dev.js:22690ExceptionHandler.call @ angular2.dev.js:1172(匿名函数)@ angular2.dev.js:12416NgZone。 _notifyOnError @ angular2.dev.js:13324collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:13228run @ angular2-polyfills.js:141(匿名函数)@ angular2.dev.js:13247NgZone.run @ angular2.dev。 js:13209(匿名函数)@angular2.dev.js:12499schedulerFn@angular2.dev.js:12742tryCatcher@Rx.js:31Subscriber.next@Rx.js:9500Subject._next@Rx.js:9999Subject.next@Rx。 js:9963EventEmitter.emit@angular2.dev.js:12723(匿名函数)@angular2.dev.js:13140run@angular2-polyfills.js:138NgZone._notifyOnTurnDone@angular2.dev.js:13139(匿名函数)@angular2。 dev.js:13254zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305 angular2.dev.js:22690 原始堆栈跟踪:BrowserDomAdapter.logError @ angular2.dev.js:22690ExceptionHandler.call @ angular2.dev.js:1175(匿名函数)@ angular2.dev.js:12416NgZone._notifyOnError @ angular2.dev。 js:13324collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:13228run @ angular2-polyfills.js:141(匿名函数)@ angular2.dev.js:13247NgZone.run @ angular2.dev.js:13209(匿名函数) @ angular2.dev.js:12499schedulerFn @ angular2.dev.js:12742tryCatcher @ Rx.js:31Subscriber.next @ Rx.js:9500Subject._next @ Rx.js:9999Subject.next @ Rx.js:9963EventEmitter.emit @ angular2.dev.js:12723(匿名函数) @ angular2.dev.js:13140run @ angular2-polyfills.js:138NgZone._notifyOnTurnDone @ angular2.dev.js:13139(匿名函数) @ angular2.dev.js:13254zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305 angular2.dev.js:22690 TypeError: viewFactory_ComponentB0 不是函数 在 AppElement.viewFactory_ComponentA1 [作为 EmbeddedViewFactory] ​​(viewFactory_ComponentA:388) 在 AppViewManager_.createEmbeddedViewInContainer (angular2.dev.js:9185) 在 ViewContainerRef_.createEmbeddedView (angular2.dev.js:5890) 在 NgFor._bulkInsert (angular2.dev.js:14608) 在 NgFor._applyChanges (angular2.dev.js:14567) 在 NgFor.ngDoCheck (angular2.dev.js:14552) 在 AbstractChangeDetector.ChangeDetector_ComponentA_0.detectChangesInRecordsInternal (viewFactory_ComponentA:45) 在 AbstractChangeDetector.detectChangesInRecords (angular2.dev.js:7825) 在 AbstractChangeDetector.runDetectChanges (angular2.dev.js:7808) 在 AbstractChangeDetector._detectChangesInViewChildren (angular2.dev.js:7892)

组件A:

@Component(
  selector: 'component-a'
  , directives: [
    FORM_DIRECTIVES
    , ComponentB
  ]
  , template: `
    <!-- works --><component-b [(ngFormControl)]="_formControl"></component-b>
    <!-- fails --><component-b *ngFor="#number of numbers" [(ngFormControl)]="_formControls[number]"></component-b>
  `
)

export class ComponentA 

非常感谢任何提示/帮助。

【问题讨论】:

这是 beta.1 中引入的一个错误(请参阅#6404)。已经有一个修复程序(请参阅#6474),因此如果您想避免这些错误,则必须等待下一个版本并降级到 beta.0。 你们会提供plnkr吗? 正如@EricMartinez 指出的那样,我降级到了 beta.0,现在它又可以工作了。 @EricMartinez 你能发布你的答案以便我接受吗? @TylerDurden 确定,完成。 【参考方案1】:

正如@TylerDurden 所建议的那样

此错误消息是由循环检测中引入的错误产生的(请参阅#6404)。

master 中已经有一个修复(参见#6474)尚未发布。这肯定会在 beta.2 中。

建议降级到 beta.0 直到风暴结束。

更新

此问题已在 beta.2 中修复(缩小问题仍然存在)。详情请见changelog。

【讨论】:

感谢您澄清这一点。几个小时以来,我一直在试图找出解决方法。【参考方案2】:

这个问题真的解决了吗?我正在研究“beta 0”,下面的代码对我有用,但是在更新文件时,beta 2 仍然给我带来了与这篇文章相同的问题。这是我的代码:

// rowIterator.component.ts
import Component,forwardRef from 'angular2/core';
import ColumIteratorComponent from './columIterator.component';
import ModuleIteratorComponent from './moduleIterator.component';

@Component(
  selector: '[rowIterator]',
  template: `
    <div *ngFor="#element of rowData">
      <div columIterator *ngIf="element.column" [ngClass]="element.class" [columData]="element.column"></div>

      <div moduleIterator *ngIf="element.module" [ngClass]="element.class" [moduleData]="element.module"></div>
    </div>
    `,
  inputs: ['rowData'],
  directives: [forwardRef(function()  return ColumIteratorComponent; ),ModuleIteratorComponent]
)
export class RowIteratorComponent 
  // "rowData" is a ARRAYS


//columnIterator.components.ts
import Component,forwardRef from 'angular2/core';
import RowIteratorComponent from './rowIterator.component';
import ModuleIteratorComponent from './moduleIterator.component';

@Component(
  selector: '[columIterator]',
  template:`
    <div *ngFor="#element of columData">
      <div rowIterator *ngIf="element.row" [ngClass]="element.class" [rowData]="element.row"></div>

      <div moduleIterator *ngIf="element.module" [ngClass]="element.class" [moduleData]="element.module"></div>
    </div>
  `,
  inputs: ['columData'],
  directives: [forwardRef(function()return RowIteratorComponent;), ModuleIteratorComponent]
)
export class ColumIteratorComponent
  // "columData" is a ARRAY

我在Beta 0版本中必须分别使用forwardRef(function() return RowIteratorComponent;函数和forwardRef(function() return ColumIteratorComponent;)进行循环并且没有问题,但是在Versioned beta2中得到以下错误:

EXCEPTION: TypeError: viewFactory_ColumIteratorComponent0 is not a function in [element.column in RowIteratorComponent@2:25]
EXCEPTION: TypeError: viewFactory_ColumIteratorComponent0 is not a function in [element.column in RowIteratorComponent@2:25]BrowserDomAdapter.logError @ angular2.dev.js:22911BrowserDomAdapter.logGroup @ angular2.dev.js:22922ExceptionHandler.call @ angular2.dev.js:1182(anonymous function) @ angular2.dev.js:12562NgZone._notifyOnError @ angular2.dev.js:13485collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:13389Zone.run @ angular2-polyfills.js:1247(anonymous function) @ angular2.dev.js:13408NgZone.run @ angular2.dev.js:13370(anonymous function) @ angular2.dev.js:12661schedulerFn @ angular2.dev.js:12904tryCatcher @ Rx.js:234Subscriber.next @ Rx.js:9703Subject._next @ Rx.js:10202Subject.next @ Rx.js:10166EventEmitter.emit @ angular2.dev.js:12885(anonymous function) @ angular2.dev.js:13301Zone.run @ angular2-polyfills.js:1243NgZone._notifyOnTurnDone @ angular2.dev.js:13300(anonymous function) @ angular2.dev.js:13415zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:468lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:480lib$es6$promise$$internal$$publish @ angular2-polyfills.js:451(anonymous function) @ angular2-polyfills.js:123Zone.run @ angular2-polyfills.js:1243zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$asap$$flush @ angular2-polyfills.js:262
angular2.dev.js:22911 ORIGINAL EXCEPTION: TypeError: viewFactory_ColumIteratorComponent0 is not a functionBrowserDomAdapter.logError @ angular2.dev.js:22911ExceptionHandler.call @ angular2.dev.js:1191(anonymous function) @ angular2.dev.js:12562NgZone._notifyOnError @ angular2.dev.js:13485collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:13389Zone.run @ angular2-polyfills.js:1247(anonymous function) @ angular2.dev.js:13408NgZone.run @ angular2.dev.js:13370(anonymous function) @ angular2.dev.js:12661schedulerFn @ angular2.dev.js:12904tryCatcher @ Rx.js:234Subscriber.next @ Rx.js:9703Subject._next @ Rx.js:10202Subject.next @ Rx.js:10166EventEmitter.emit @ angular2.dev.js:12885(anonymous function) @ angular2.dev.js:13301Zone.run @ angular2-polyfills.js:1243NgZone._notifyOnTurnDone @ angular2.dev.js:13300(anonymous function) @ angular2.dev.js:13415zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:468lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:480lib$es6$promise$$internal$$publish @ angular2-polyfills.js:451(anonymous function) @ angular2-polyfills.js:123Zone.run @ angular2-polyfills.js:1243zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$asap$$flush @ angular2-polyfills.js:262
angular2.dev.js:22911 ORIGINAL STACKTRACE:BrowserDomAdapter.logError @ angular2.dev.js:22911ExceptionHandler.call @ angular2.dev.js:1194(anonymous function) @ angular2.dev.js:12562NgZone._notifyOnError @ angular2.dev.js:13485collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:13389Zone.run @ angular2-polyfills.js:1247(anonymous function) @ angular2.dev.js:13408NgZone.run @ angular2.dev.js:13370(anonymous function) @ angular2.dev.js:12661schedulerFn @ angular2.dev.js:12904tryCatcher @ Rx.js:234Subscriber.next @ Rx.js:9703Subject._next @ Rx.js:10202Subject.next @ Rx.js:10166EventEmitter.emit @ angular2.dev.js:12885(anonymous function) @ angular2.dev.js:13301Zone.run @ angular2-polyfills.js:1243NgZone._notifyOnTurnDone @ angular2.dev.js:13300(anonymous function) @ angular2.dev.js:13415zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:468lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:480lib$es6$promise$$internal$$publish @ angular2-polyfills.js:451(anonymous function) @ angular2-polyfills.js:123Zone.run @ angular2-polyfills.js:1243zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$asap$$flush @ angular2-polyfills.js:262
angular2.dev.js:22911 TypeError: viewFactory_ColumIteratorComponent0 is not a function...

【讨论】:

以上是关于ngFor 中的 Angular2 组件抛出错误(viewFactory 不是函数)的主要内容,如果未能解决你的问题,请参考以下文章

angular2你如何在`ngFor`中渲染一个计时器组件

Angular2:嵌套 *ngFor 导致“检查后表达式已更改”

*ngFor 如何与 Angular 2 中的模板变量一起工作?

Angular2 NgFor在表达式中绑定数组

Firebase列表的嵌套Angular2 ngFor指令[重复]

angular2中的[ngFor]和[ngForOf]有啥区别?