web-dev-qa-db-ja.com

テンプレートバインディングでangular 4からゲッター/セッターアクセサーにアクセスする方法は?

私が次のゲッター/セッターメソッドを持っているとしましょう

get next() {
  console.log(this.people[this._index], this._index);
  return this.people[this._index];
}

set next(i: any) {
  this._index = (+i) + 1;
  this._index = (+i) % this.people.length;
}

そして私はこれを次のように呼びたいです:

<ng-template ngFor let-person="$implicit" [ngForOf]="people" let-i=index let-last=last>
  <app-card [cardItem]="people[i]" [nextCard]="next(i)"></app-card>
</ng-template>

PS:これを循環配列と考えてください。前、現在、次のアイテムが必要な場所。

ただし、次のエラーが発生します

Angular:メンバー 'next'は呼び出し不可能です

何故ですか?そして、解決策は何ですか?

ありがとう

編集する

あなたの助けと説明をありがとう。あなたの助けを借りて、私はそれをうまく動かすことができました:

<app-card [currentCard]="people[i]" [nextCard]="people[i === people.length - 1 ? 0: i + 1]" [prevCard]="i == 0 ? people[people.length - 1] : people[i - 1]"></app-card>

そのため、ほぼ円形の配列です。次のものがあるとしましょう:

people["James Dan", "Aluan Haddad", "Jota Toledo"]

だからいくつかの条件:

  1. 配列の最初に立っている場合(つまり、index = 0)-prevは、配列の最後の要素であるpeople[people.length - 1]になります。そして、私の現在がインデックス1にある場合、私の前はインデックス0になり、次はインデックス2になります。
4
James

Angularテンプレート構文は、通常、JavaScript構文のサブセットであり、いくつかの顕著な違いと多くの制限があります。

ただし、ここにあるものは実際にはJavaScriptでも無効です。プロパティアクセサーを呼び出すことはできません。ずっと。

次のプロパティを考える

get p() {
  console.info('read p');
  return this.wrapped;
}
set p(value) {
  console.info('wrote p');
  this.wrapped = value;
}

getアクセサーは、このように名前が付けられたプロパティが読み取られるときに暗黙的に呼び出されます。

例えば:

console.log(o.p); // read p

setアクセサーは、このように名前が付けられたプロパティが書き込まれるときに暗黙的に呼び出されます。

例えば:

o.p = x; // wrote p;

同じルールがAngularテンプレートにも適用されます。

ただし、あなたの例

<app-card [cardItem]="people[i]" [nextCard]="next(i)">

プロパティは、ここで必要なものではないことを示唆しています。

プロパティの正しい使用法は、次の構文を意味します

<app-card [cardItem]="people[i]" [nextCard]="next = i">

Angularテンプレート構文によってサポートされていると私が信じていないことは、たとえそれが多くの意味をなさなくても、読みにくくてもです。

代わりに、値を返すメソッドを作成する必要があります

getNext(i: number) {
  this._index = i + 1;
  this._index = i % this.people.length;
  return this.people[this._index];
}

その後、テンプレートで次のように使用されます

<app-card [cardItem]="people[i]" [nextCard]="getNext(i)">

そうは言っても、デザイン全体が疑わしいと思います。自然に維持している配列とは無関係に、過剰な可変状態を保存するためのゆがみを経験しているようです。

メソッドとプロパティを完全に削除して使用することで、より良いサービスを提供できると思います

<app-card
  *ngFor="let person of people; let i = index"
  [previousCard]="people[i === 0 ? people.length - 1 : i - 1]" 
  [cardItem]="person"
  [nextCard]="people[i === people.length - 1 ? 0 : i + 1]">

より簡潔な構文が必要な場合は、getprevious、およびcurrentプロパティを持つオブジェクトとして配列のビューを返す、nextアクセサーのみでプロパティを定義できます。

get peopleAsPreviousCurrentAndNextTriplets() {
  return this.people.map((person, i) => ({
    previous: this.people[i === 0 ? this.people.length - 1 : i - 1],
    current: person,
    next: this.people[i === this.people.length - 1 ? 0 : i + 1]
  }));
}

これは複雑なコードで読みやすくなる可能性があります。これは、直接使用できるセマンティックプロパティのインデックスを抽象化するためです。おそらくもっと重要なことは、TypeScriptのワールドクラスのツールが計算を検証できるようにすることです。

<app-card
  *ngFor="let item of peopleAsPreviousCurrentAndNextTriplets"
  [previousCard]="item.previous" 
  [cardItem]="item.current"
  [nextCard]="item.next">

そして、私たちは一周します。 getアクセサーを定義する方法と、()なしで定義するプロパティを読み取る方法に注意してください。暗黙的にそのアクセサーを呼び出します。

最後の例はおそらくこのシナリオではやり過ぎですが、それでもそれは有用だと思います。

13
Aluan Haddad