1

この plnkerはおそらく問題を確認する最も簡単な方法です

ViewChild を使用するときの明らかな落とし穴なのかどうかはわかりませんが、非常に奇妙です。

プランカーは 3 つの入力を示しています。

  • 最初の入力は、基本的な入力と、それをフォーカスできるボタンです。
  • 2 番目の入力は同じ値にバインドされており、[編集] をクリックすると入力のロックが解除されます。
  • 3 番目の入力も同じ値にバインドされており、[編集] をクリックすると入力のロックが解除され、フォーカスが与えられます。

ただし、ViewChild を追加して入力への参照を取得すると、入力に対する NgModel バインディングが機能しなくなります。ただし、アタッチする他のバインド (無効化など) は引き続き機能します。app/extended.component の 52 行目をコメントアウトすると、再びバインドされますが、明らかにフォーカスできなくなります。

最初の入力/ボタンは、これが明らかに、拡張しているクラスのプロパティにバインドしている場合にのみ問題であることを示しています。


つまり、ViewChild を介して入力にアクセスすると、NgModel へのバインディングが壊れます。

つまり、プロパティ「someValue」を持つベースが与えられた場合:

@Component({
  selector: 'binding-working',
  template: `<input type="text" [(ngModel)]="someValue" />`
})
export class Working extends Base<string> {  
  constructor() { }
};

バインドしない:

@Component({
  selector: 'binding-broken',
  template: `<input type="text" #imBroken [(ngModel)]="someValue" />`
})
export class Broken extends Base<string> {  
  @ViewChild('imBroken') input;
  constructor() { }
};
4

1 に答える 1

7

アップデート 2.3.0

素晴らしいニュース!

角度ブログによるとhttp://angularjs.blogspot.ru/2016/12/angular-230-now-available.html

開発者は、コンポーネントのオブジェクト継承を利用できるようになりました。親コンポーネントから継承することで、コンポーネントの機能を共有または簡素化します。

したがって、カスタムデコレータなしで動作するはずです => Plunker Example

このコミットで詳細を確認できますhttps://github.com/angular/angular/commit/f5c8e0989d85bc064f689fc3595207dfb29413f4

古いバージョン

設計通りです。

Angular2 は完全な継承をサポートしていません ( https://github.com/angular/angular/issues/7968#issuecomment-219865739 )。

基本クラスで定義された子ViewChildデコレーターのオーバーライド。したがって、クラスにはおよびのような親プロパティがありませんpropMetadataExtendedExtendedInputBrokenbaseLevelbaseLevelChange

Thierry Templierが Angular2 のクラス継承に関する素晴らしい記事を書きました

あなたが本当にそれをしたいのなら、私はあなたに次の解決策を提供することができます.

次のようなカスタム デコレータを作成するだけです。

function InheritPropMetadata() {
  return (target: Function) => {
    const targetProps = Reflect.getMetadata('propMetadata', target);

    const parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    const parentProps = Reflect.getMetadata('propMetadata', parentTarget);

    const mergedProps = Object.assign(targetProps, parentProps);

    Reflect.defineMetadata('propMetadata', mergedProps, target);
  };
};

そして、それをExtendedInputBrokenクラスに適用します。

@InheritPropMetadata()
export class ExtendedInputBroken extends Extended<string> implements OnInit {
  ...

プランカーのデモ

このリンクはあなたに興味があるかもしれません:

于 2016-07-02T05:21:32.600 に答える