如何在模板绑定中从 angular 4 访问 getter/setter 访问器?
How to access getter/setter accessors from angular 4 in template binding?
假设我有以下 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;
}
我想通过以下方式调用它:
<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: Member 'next' in not callable
这是为什么?解决方案是什么?
谢谢
编辑
谢谢大家的帮助和解释。在你的帮助下,我设法让它工作:
<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"]
条件太少:
- 如果我站在数组的开头(即
index = 0
)- 那么我的 prev
将是 people[people.length - 1]
,这是数组中的最后一个元素。如果我的电流在索引 1 上,那么我的上一个将是索引 0,下一个将是索引 2。
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 模板语法不支持,即使它没有多大意义,也很难阅读。
相反,您应该创建一个 returns 值
的方法
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]">
如果你想要一个更清晰的语法,你可以定义一个 属性,只有一个 get
访问器,returns 你的数组的视图作为对象 previous
、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 的 world-class 工具来验证计算。
<app-card
*ngFor="let item of peopleAsPreviousCurrentAndNextTriplets"
[previousCard]="item.previous"
[cardItem]="item.current"
[nextCard]="item.next">
这样我们又绕了一圈。请注意我们如何定义 get
访问器,以及我们如何在不使用 ()
的情况下读取它定义的 属性,隐式调用该访问器。
最后一个示例对于这种情况可能有些过分,但我认为它仍然有用。
假设我有以下 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;
}
我想通过以下方式调用它:
<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: Member 'next' in not callable
这是为什么?解决方案是什么?
谢谢
编辑
谢谢大家的帮助和解释。在你的帮助下,我设法让它工作:
<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"]
条件太少:
- 如果我站在数组的开头(即
index = 0
)- 那么我的prev
将是people[people.length - 1]
,这是数组中的最后一个元素。如果我的电流在索引 1 上,那么我的上一个将是索引 0,下一个将是索引 2。
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 模板语法不支持,即使它没有多大意义,也很难阅读。
相反,您应该创建一个 returns 值
的方法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]">
如果你想要一个更清晰的语法,你可以定义一个 属性,只有一个 get
访问器,returns 你的数组的视图作为对象 previous
、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 的 world-class 工具来验证计算。
<app-card
*ngFor="let item of peopleAsPreviousCurrentAndNextTriplets"
[previousCard]="item.previous"
[cardItem]="item.current"
[nextCard]="item.next">
这样我们又绕了一圈。请注意我们如何定义 get
访问器,以及我们如何在不使用 ()
的情况下读取它定义的 属性,隐式调用该访问器。
最后一个示例对于这种情况可能有些过分,但我认为它仍然有用。