如何在模板绑定中从angular 4访问getter/setter访问器? [英] How to access getter/setter accessors from angular 4 in template binding?

查看:181
本文介绍了如何在模板绑定中从angular 4访问getter/setter访问器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有以下getter/setter方法

Lets say I have the following getter/setter methods

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

我想用以下方式称呼它:

and I want to call this in the following way:

<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:将其视为圆形阵列.在哪里需要上一个,当前和下一个项目.

PS: Think of this as circular array. Where by I need prev, current, and next items.

但是我遇到以下错误

角度:成员"next"处于不可调用状态

Angular: Member 'next' in not callable

那是为什么?那么解决方案是什么?

Why is that? And whats the solution?

谢谢

谢谢你们的帮助和解释.在您的帮助下,我设法使它起作用:

Thank you guys for your help and explanation. With your help i managed to make it work:

<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>

所以它几乎是圆形数组. 假设我们有以下内容:

So its pretty much circular array. Lets assume we have the following:

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

那么少的条件:

  1. 如果我站在数组的开头(即index = 0)-那么我的prev将是people[people.length - 1],这是数组中的最后一个元素.如果我当前的位置是索引1,那么我的上一个将是索引0,下一个将是索引2.
  1. If I stand in the beginning of the array (i.e. index = 0) - then my prev will be people[people.length - 1] which is the last element in the array. And if my current is on index 1, then my prev will be index 0 and next will be index 2.

推荐答案

通常,Angular模板语法是JavaScript语法的子集,具有一些显着的区别并且有很多限制.

The Angular template syntax is, in general, a subset of JavaScript syntax with some notable differences and with many restrictions.

但是,这里的内容实际上在JavaScript中也是无效的.调用属性访问器无效.曾经.

However what you have here is actually invalid in JavaScript as well. It is not valid to call a property accessor. Ever.

给出以下属性

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

读取由此命名的属性时,将隐式调用get访问器.

The get accessor is invoked implicitly when the property thusly named is read.

例如:

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

写入这样命名的属性时,会隐式调用set访问器.

The set accessor is invoked implicitly when the property thusly named is written.

例如:

o.p = x; // wrote p;

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

The same rules apply in Angular templates.

但是,您的示例

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

建议您在这里不想要某个属性.

suggests that a property is not what you want here.

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

The correct usage of a property implies the following syntax

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

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

Which I do not believe is supported by the Angular template syntax and even if it is doesn't make a lot of sense and would be hard to read.

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

Instead you should create a method that returns a value

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)">

话虽如此,我认为整个设计还是有问题的.您似乎正在经历扭曲,以存储多余的可变状态,而与自然保持状态的数组无关.

Having said that, I think the entire design is questionable. You seem to be going through contortions to store excess mutable state independently of the array that naturally maintains it.

我相信通过完全删除方法和属性并使用

I believe you would be much better served by removing the method and the property entirely and using

<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访问器的属性,该属性以具有previouscurrentnext属性的对象的形式返回数组的视图.

If you want a cleaner syntax, you might define a property, with a get accessor only, that returns a view of your array as objects with previous, current, and next properties.

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的世界一流工具能够验证计算.

This can be more readable in complex code because its abstracts away the index for more semantic properties that we can use directly. Perhaps more importantly, it enables TypeScript's world-class tooling to validate the computation.

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

因此,我们走了一个完整的圈子.请注意,我们如何定义get访问器,以及如何在不使用()的情况下隐式调用该访问器来读取它定义的属性.

And thus we come full circle. Note how we define the get accessor and how we read the property it defines without (), implicitly invoking that accessor.

在这种情况下,最后一个例子可能是矫kill过正,但我​​认为它仍然很有用.

The last example is probably overkill for this scenario but I think it's useful nonetheless.

这篇关于如何在模板绑定中从angular 4访问getter/setter访问器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆