【问题标题】:Angular 4 doesn't care about the Elvis operator (?.)Angular 4 不关心 Elvis 运算符 (?.)
【发布时间】:2018-04-11 18:01:48
【问题描述】:

Elvis 运算符(也称为安全导航运算符)应该避免在尝试访问 JavaScript 对象中的“未定义”方法时导致页面崩溃,对吧?

好吧,也许不是,也许我做错了什么。检查此代码:

<ion-content padding>
  <h3>"{{place?.get("placeName")}}" management</h3>
  <ion-list>
    <ion-item *ngFor="let visit of visitBuffer">
      User: {{visit?.get("userId")}}
    </ion-item>
  </ion-list>
</ion-content>

(是的,它是一个运行 Angular 4 的 Ionic 应用程序)。

所以我只是想查看每个项目的每个对象“访问”的用户 ID。应该问题不大吧?我在构造函数中运行的两个不同的并行查询中加载了 visitBuffer 的所有信息:

export class Management {

  place;
  visitBuffer = [];

  constructor(
    public navCtrl: NavController,
    public navParams: NavParams
  ) {
    const placeId = localStorage.getItem("placeId");
    this.getPlace(placeId)
        .then( place => {
          this.place = place;
          // Subscribe to normal Visits
          this.subscribeVisits(placeId).then( subscription => {
            let s = <any> subscription;
            s.on('create', (visit) => {
              this.visitBuffer.push(visit);
            });
          })
          // Subscribe to GroupVisits
          this.subscribeGroupVisits(placeId).then( subscription => {
            let s = <any> subscription;
            s.on('create', (visit) => {
              this.visitBuffer.push(visit);
            });
          })
        })
  }

您在那里看到的方法,只是查询 Parse 数据库并返回一些对象或数组。他们只是将对象推入“visitBuffer”并将 .map 函数应用于数组,将它们的数据重新分配到与以前相同的“visitBuffer”数组中。这是为了让两个相似的对象(Visits 和 VisitGroups)进入同一个数组,因为在我看来,我将平等地处理它们。

我只是想获取 Parse 方法“.get(property)”,所以我可以获取两种类型的对象都具有的属性 usedId。而且我什至在使用 elvis 运算符,但是......它无论如何都会抛出错误:

VM1194 Management.ngfactory.js:13 ERROR TypeError: _v.context.$implicit.get is not a function
    at Object.eval [as updateRenderer] (VM174 Management.ngfactory.js:15)
    at Object.debugUpdateRenderer [as updateRenderer] (VM82 vendor.js:13488)
    at checkAndUpdateView (VM82 vendor.js:12632)
    at callViewAction (VM82 vendor.js:12995)
    at execEmbeddedViewsAction (VM82 vendor.js:12953)
    at checkAndUpdateView (VM82 vendor.js:12628)
    at callViewAction (VM82 vendor.js:12995)
    at execComponentViewsAction (VM82 vendor.js:12927)
    at checkAndUpdateView (VM82 vendor.js:12633)
    at callViewAction (VM82 vendor.js:12995)

我是不是做错了什么……?为什么我在使用 elvis 运算符时视图会崩溃?

【问题讨论】:

  • place 实际上是什么?此错误更多地表明place 没有get 方法。这是正确的,因为place 是“只是一个变量”。
  • @AJT_82 失败不是发生在 place 对象上,而是发生在 visitBuffer 对象上
  • 那么,visit 是什么?它似乎“也只是一个变量”?
  • 次要,但 ?: 是 Elvis 运算符,是 null-coalescing 运算符的一种形式。 AFAIK ?. 没有一个有趣的名字,但它在 Angular 中的名字是“安全导航运算符”。

标签: javascript angular ionic-framework


【解决方案1】:

我过去遇到过类似的问题。看看*ngIf 是否有帮助:

 <ion-list *ngIf="visitBuffer">
    <ion-item *ngFor="let visit of visitBuffer">
      User: {{visit.get("userId")}}
    </ion-item>
  </ion-list>

【讨论】:

  • 这听起来可能很奇怪,但是......即使使用 ngIf 也会失败。也许是因为我的 visitBuffer 被初始化为 []?
  • 除非你真的想隐藏离子列表,否则实际上不需要 ngIf。一旦项目存在,ngFor 将循环,因此如果它是一个空列表,则无论如何都不会显示任何内容。 @Zerok,检查这一点的最快方法是在某处运行 !![] 并记录输出。这将输出 true 所以确实是因为初始化
【解决方案2】:

好的,我解决了这个问题,虽然我刚刚意识到一个有趣的事实,关于 Elvis 运算符。

我瞄准的变量(usedId)对于“GroupVisit”类型不存在,因此当该类型的一个对象到达时,它崩溃了。问题是,elvis 运算符似乎首先检查变量的类型,然后对来自数组的每个值应用相同的规则。

我认为 elvis 运算符会检查每个对象中的 null 值,但它似乎只是在第一次执行。我必须对填充“visitBuffer”的方式进行一些更改,这样我就不会再遇到这个问题了:我可以使用不同的数组,或者只是将属性添加到 GroupVisit 对象。第二个选项效果很好。

无论如何,对于这种情况,我们有一个动态类型的数组,我们应该有某种类型的“循环 elvis 运算符”,它在循环的每次迭代中检查空值,而不仅仅是第一个对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    相关资源
    最近更新 更多