Je rencontre un problème étrange. J'ai recherché l'erreur, et cela semble généralement être lié à l'utilisation de @Output
ou EventEmitter
, mais ce n'est pas le cas ici.
J'obtiens l'erreur suivante dans mon application si un polyfill particulier est en 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)
Le polyfill est comme suit:
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).
};
Quelqu'un peut-il m'aider à comprendre pourquoi cela pourrait causer une erreur dans createDirectiveInstance
? Si je commente ce code, l'erreur disparaît. Ce n'est pas simplement le fait d'avoir un polyfill qui pose problème, il y en a un autre qui ajoute Array.prototype.upsert
, ce qui ne pose pas de problème.
Je viens de faire face à ce problème et en vérifiant le code que j'ai écrit, j'ai découvert qu'il était dû à une mauvaise importation de la classe EventEmitter (effectuée par l'importation automatique du code Visual Studio).
Vous avez juste besoin de changer
import { EventEmitter } from 'events';
À
import { EventEmitter } from '@angular/core';
Et à propos de l'explication de l'erreur. Angular mappe les événements en tant qu'observables. Il doit donc s'abonner aux événements des composants enfants et les envoyer aux composants appropriés.
À la recherche du paquet original, j'ai trouvé son code source sur: https://github.com/Gozala/events/blob/master/events.js
Et cela échoue simplement car il n'y a pas de méthode .suscribe()
dans EventEmitter que vous avez créé.
J'ai eu le même problème et j'ai trouvé une solution qui a fonctionné pour moi.
dans les noeuds_modules/@ angular/core/@ angular/core.es5.js du projet
10768: var /** @type {?} */ subscription = instance[((output.propName))].subscribe(...
D'une manière ou d'une autre, il obtenait une propName
appelée assign
qui ne figure pas dans l'objet instance
. Il suffit de mettre et si déclaration et assurez-vous qu’il dispose d’une fonction d’abonnement avant de l’appeler. Quelque chose comme ça:
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);
}
Et vous devrez peut-être aussi vérifier ici:
12515: view.disposables[i]();
j'ai fait ça:
if (view.disposables[i] && typeof view.disposables[i] === 'function'){
view.disposables[i]();
}
Je ne recommanderais pas ce patch de singe, mais cela a fonctionné pour moi et je n’ai pas eu d’erreur depuis. J'espère que cela aide ou même aide quelqu'un à trouver une meilleure solution.
Tout d’abord, c’est probablement une mauvaise idée d’implémenter une fonction de clonage non optimisée, surtout lorsque de nombreuses bibliothèques l’ont déjà implémentée [1]. Cela dit, cette réponse peut être utile si vous ne pouvez pas ajouter de bibliothèques ou à d'autres personnes comme moi qui souhaitent étendre la variable Object
.
Cela semble résulter d'une déclaration incorrecte d'une propriété sur Object.prototype
. Je suppose que createDirectiveInstance
a certaines attentes non satisfaites quand il énumère Object.clone
(il ne devrait probablement pas être énuméré). Utilisez plutôt la méthode 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
}
);
Cela pourrait être refactored au TypeScript suivant:
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
}
);
Cependant, pour obtenir une inférence de type à partir de TypeScript, je pense que vous devez également déclarer une extension à l'interface globale pour Object:
declare global {
interface Object {
clone(deep?: boolean): any;
}
}
Pour plus de ressources sur Object.defineProperty
, voir:
[1] Implémentations Javascript Clone: