web-dev-qa-db-ja.com

instance [output.propName] .subscribeは、ポリフィルの結果の関数ではありません

奇妙な問題に直面しています。私はエラーを調査しましたが、一般的に@OutputまたはEventEmitterの使用に関連しているようですが、ここではそうではありません。

特定のポリフィルを配置している場合、アプリケーションで次のエラーが発生します。

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)

ポリフィルは次のとおりです。

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).
};

なぜこれがcreateDirectiveInstance内でエラーを引き起こす可能性があるのか​​、誰でも私を理解するのを助けることができますか?このコードをコメントアウトすると、エラーは消えます。問題を引き起こすポリフィルがあるだけではありません。問題を引き起こさないArray.prototype.upsertを追加するポリフィルがあります。

18

この問題に直面したばかりで、書いたコードを確認したところ、EventEmitterクラスの不正なインポート(Visual Studioコードの自動インポートによって行われた)が原因であることがわかりました。

あなただけを変更する必要があります

_import { EventEmitter } from 'events';
_

_import { EventEmitter } from '@angular/core';
_

そして、エラーの説明について。 Angularはイベントをオブザーバブルとしてマップするため、子コンポーネントのイベントをサブスクライブし、適切なコンポーネントに送信する必要があります。

元のパッケージを探して、ソースコードを見つけました: https://github.com/Gozala/events/blob/master/events.js

そして、作成したEventEmitterにメソッド.suscribe()がないため、単に失敗します。

107
Adrian Abreu

私は同じ問題を抱えていて、自分に合った解決策を見つけました。

プロジェクトのnode_modules/@ angular/core/@ angular/core.es5.js

10768: var /** @type {?} */ subscription = instance[((output.propName))].subscribe(...

どういうわけか、propNameオブジェクトにないassignと呼ばれるinstanceを取得していました。 ifステートメントを入れて、呼び出す前にサブスクライブ関数があることを確認してください。このようなもの:

 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);
        }

また、ここで確認する必要がある場合もあります。

12515: view.disposables[i]();

これは私がしました:

if (view.disposables[i] && typeof view.disposables[i] === 'function'){
          view.disposables[i]();
}

このモンキーパッチはお勧めしませんが、私にとってはうまくいきました。それ以来、エラーは発生していません。私はそれが誰かがより良い解決策を見つけるのを助けるか、さらには助けてくれることを願っています。

0
marshy101

まず最初に、最適化されていないクローン関数を実装することは、おそらく多くのライブラリが既に実装している場合にはおそらく悪い考えです[1]。そうは言っても、ライブラリを追加できない場合、またはObjectを拡張しようとしている私のような他の人にとって、この答えは役に立つかもしれません。

これは、Object.prototypeでプロパティを不適切に宣言した結果のようです。 Object.cloneを列挙するときにcreateDirectiveInstanceが期待する満たされていないものがあると推測しています(おそらく列挙すべきではありません)。代わりに、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 Cloneの実装:

0
Anonymous