如何从模板绑定中的角度4访问getter/setter访问器?

Jam*_*mes 4 templatebinding getter-setter typescript angular

假设我有以下getter/setter方法

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;
}
Run Code Online (Sandbox Code Playgroud)

我想用以下方式调用它:

<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>
Run Code Online (Sandbox Code Playgroud)

PS:把它想象成圆形阵列.我在哪里需要prev,current和next items.

但是我得到以下错误

Angular:会员'下一个'不可赎回

这是为什么?最新解决方案是什么?

谢谢

编辑

谢谢你们的帮助和解释.在你的帮助下,我设法让它发挥作用:

<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>
Run Code Online (Sandbox Code Playgroud)

所以它几乎是圆形阵列.让我们假设我们有以下内容:

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

条件很少:

  1. 如果我站在数组的开头(即index = 0) - 那么我的prev将是people[people.length - 1]数组中的最后一个元素.如果我的当前是在索引1上,那么我的上一个将是索引0,接下来将是索引2.

Alu*_*dad 15

Angular模板语法通常是JavaScript语法的一个子集,具有一些显着的差异和许多限制.

但是你在这里拥有的JavaScript实际上也是无效的.调用属性访问器无效.永远.

鉴于以下财产

get p() {
  console.info('read p');
  return this.wrapped;
}
set p(value) {
  console.info('wrote p');
  this.wrapped = value;
}
Run Code Online (Sandbox Code Playgroud)

get时正是如此命名的属性是读访问被隐式调用.

例如:

console.log(o.p); // read p
Run Code Online (Sandbox Code Playgroud)

set正是如此命名的财产被写入时访问被隐式调用.

例如:

o.p = x; // wrote p;
Run Code Online (Sandbox Code Playgroud)

Angular模板中适用相同的规则.

但是,你的例子

<app-card [cardItem]="people[i]" [nextCard]="next(i)">
Run Code Online (Sandbox Code Playgroud)

建议财产不是你想要的.

正确使用属性意味着以下语法

<app-card [cardItem]="people[i]" [nextCard]="next = i">
Run Code Online (Sandbox Code Playgroud)

我不相信Angular模板语法支持,即使它没有多大意义,也很难阅读.

相反,您应该创建一个返回值的方法

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

然后在您的模板中使用

<app-card [cardItem]="people[i]" [nextCard]="getNext(i)">
Run Code Online (Sandbox Code Playgroud)

话虽如此,我认为整个设计都值得怀疑.您似乎正在通过扭曲来存储多余的可变状态,而不依赖于自然维护它的数组.

我相信通过完全删除方法和属性以及使用它会更好

<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]">
Run Code Online (Sandbox Code Playgroud)

如果你想有一个更清晰的语法,您可以定义一个属性,具有get唯一的访问,返回你的数组与对象的视图previous,currentnext性能.

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]
  }));
}
Run Code Online (Sandbox Code Playgroud)

这在复杂代码中可以更具可读性,因为它抽象了索引以获得我们可以直接使用的更多语义属性.也许更重要的是,它使TypeScript的世界级工具能够验证计算.

<app-card
  *ngFor="let item of peopleAsPreviousCurrentAndNextTriplets"
  [previousCard]="item.previous" 
  [cardItem]="item.current"
  [nextCard]="item.next">
Run Code Online (Sandbox Code Playgroud)

因此我们走了一圈.注意我们如何定义get访问器以及我们如何读取它定义的属性(),隐式调用该访问器.

最后一个例子对于这种情况可能有些过分,但我认为它仍然有用.

  • @James你的问题没有提到关于prev的任何事情.更新你的问题,如果那是它的一部分...... (2认同)