I'm running into a strange issue. I've researched the error, and it generally seems to be related to the use of @Output
or EventEmitter
, but that's not the case here.
I get the following error in my application if I have a particular polyfill in place:
TypeError: instance[output.propName].subscribe is not a function
at createDirectiveInstance (http://localhost:9876/_karma_webpack_/webpack:/Users/stuart/localhost/projects/tt-new/work-group/node_modules/@angular/core/esm5/core.js:12319:71)
at createViewNodes (http://localhost:9876/_karma_webpack_/webpack:/Users/stuart/localhost/projects/tt-new/work-group/node_modules/@angular/core/esm5/core.js:13776:38)
at callViewAction (http://localhost:9876/_karma_webpack_/webpack:/Users/stuart/localhost/projects/tt-new/work-group/node_modules/@angular/core/esm5/core.js:14210:1)
at execComponentViewsAction (http://localhost:9876/_karma_webpack_/webpack:/Users/stuart/localhost/projects/tt-new/work-group/node_modules/@angular/core/esm5/core.js:14119:1)
at createViewNodes (http://localhost:9876/_karma_webpack_/webpack:/Users/stuart/localhost/projects/tt-new/work-group/node_modules/@angular/core/esm5/core.js:13804:1)
at createRootView (http://localhost:9876/_karma_webpack_/webpack:/Users/stuart/localhost/projects/tt-new/work-group/node_modules/@angular/core/esm5/core.js:13665:1)
at callWithDebugContext (http://localhost:9876/_karma_webpack_/webpack:/Users/stuart/localhost/projects/tt-new/work-group/node_modules/@angular/core/esm5/core.js:15090:26)
at Object.debugCreateRootView [as createRootView] (http://localhost:9876/_karma_webpack_/webpack:/Users/stuart/localhost/projects/tt-new/work-group/node_modules/@angular/core/esm5/core.js:14373:1)
at ComponentFactory_.webpackJsonp.../../../core/esm5/core.js.ComponentFactory_.create (http://localhost:9876/_karma_webpack_/webpack:/Users/stuart/localhost/projects/tt-new/work-group/node_modules/@angular/core/esm5/core.js:11260:26)
at initComponent (http://localhost:9876/_karma_webpack_/webpack:/Users/stuart/localhost/projects/tt-new/work-group/node_modules/@angular/core/esm5/testing.js:1137:1)
The polyfill is as follows:
Object.prototype.clone = function(deep = false) {
return (deep)
? JSON.parse(JSON.stringify(this)) // Deep clone - copies object property values in full.
: Object.assign({}, this); // Shallow clone - copies property values (including object references rather than object).
};
Can anyone help me understand why this might cause an error inside createDirectiveInstance
? If I comment this code out, the error goes away. It's not simply having a polyfill that causes problems - there's another, which adds Array.prototype.upsert
, which doesn't cause problems.
答案 0 :(得分:99)
我刚刚遇到这个问题并检查了我编写的代码,我发现它是由于EventEmitter类导入错误(由visual studio代码的自动导入完成)引起的。
您只需要更改
import { EventEmitter } from 'events';
要
import { EventEmitter } from '@angular/core';
关于错误说明。 Angular将事件映射为可观察对象,因此它必须订阅子组件'事件并将它们发送给适当的组件。
寻找原始包我在https://github.com/Gozala/events/blob/master/events.js
找到了它的源代码它只是失败了,因为你创建的EventEmitter中没有方法.suscribe()
。
答案 1 :(得分:0)
首先,实现未优化的克隆函数可能是一个坏主意,特别是当许多库已经实现它时[1]。话虽如此,如果您无法添加库,或者像我这样希望扩展Object
的其他人,这个答案可能会有用。
这似乎是在Object.prototype
上不正确地声明属性的结果。我猜测createDirectiveInstance
列举Object.clone
时有一些未满足的期望(它可能不应该枚举它)。相反,请使用Object.defineProperty
方法:
Object.defineProperty(
Object.prototype,
'clone',
{
value: function (deep = false) {
return (deep)
? JSON.parse(JSON.stringify(this)) // Deep clone - copies object property values in full.
: Object.assign({}, this); // Shallow clone - copies property values (including object references rather than object).
},
writable: false,
enumerable: false
}
);
可以重构为以下的Typescript:
function CloneThis(deep = false): any {
return (deep)
? JSON.parse(JSON.stringify(this)) // Deep clone - copies object property values in full.
: Object.assign({}, this); // Shallow clone - copies property values (including object references rather than object).
}
Object.defineProperty(Object.prototype, 'clone',
<PropertyDescriptor>{
value: CloneThis,
writable: false,
enumerable: false
}
);
但是,要从TypeScript获取类型推断,我认为您还需要声明Object的全局接口的扩展:
declare global {
interface Object {
clone(deep?: boolean): any;
}
}
有关Object.defineProperty
的更多资源,请参阅:
[1] Javascript克隆实现:
答案 2 :(得分:0)
我有同样的问题,我找到了一个适合我的解决方案。
在项目的node_modules / @ angular / core / @ angular / core.es5.js
10768: var /** @type {?} */ subscription = instance[((output.propName))].subscribe(...
不知怎的,它被propName
称为assign
,而instance
对象上没有 if (instance[((output.propName))] && typeof instance[((output.propName))].subscribe === 'function'){
var /** @type {?} */ subscription = instance[((output.propName))].subscribe(eventHandlerClosure(view, /** @type {?} */ ((def.parent)).index, output.eventName)); /** @type {?} */
((view.disposables))[def.outputIndex + i] = subscription.unsubscribe.bind(subscription);
}
。只需put和if语句并确保它在调用之前有一个订阅函数。像这样的东西:
12515: view.disposables[i]();
您可能还需要在此处进行检查:
if (view.disposables[i] && typeof view.disposables[i] === 'function'){
view.disposables[i]();
}
我这样做了:
lists=lists.stream()
.sorted(Comparator.comparing(ObjModel::getModifiedtime).reversed())
.collect(Collectors.toList());
我不推荐这个猴子补丁,但它对我有用,到目前为止我没有任何错误。我希望它有助于甚至帮助某人找到更好的解决方案。
答案 3 :(得分:-2)
我发现您不小心使用装饰了@Output
的方法而不是属性,可能会遇到此错误。
例如,如果您拥有:
<app-thing (onReady)="...">
</app-thing>
确保在子组件中具有:
@Output() onReady: Observable<...>
或:
@Output() get onReady(): Observable<...> {
...
}
...否:
@Output() onReady(): Observable<...> {
...
}