【问题标题】:Promise for *ngFor in Angular2Angular2 中 *ngFor 的承诺
【发布时间】:2017-05-05 21:23:50
【问题描述】:

我正在使用 angular2,我正在尝试从 *ngFor- 循环内加载的元素获取 .style.width 属性。我想用它来定义一些其他元素的宽度。这应该在页面加载时完成。我不想将宽度存储为我的代码中的某个变量。我想直接从dom中获取。

承诺:

let kistenPromise = new Promise(function(resolve, reject){

            let itemListContainer = document.getElementById("itemContainer");

                if(itemListContainer.children[0] != undefined){
                    resolve(itemListContainer.children);    
                }else{
                    reject(Error("Promise was not fullfilled!"));
                }
}.bind(this));

处理程序:

kistenPromise.then(
        function(result){
            console.log(result);
        }.bind(this), function(err){
            console.log(err);
        }.bind(this));

html:

<div class="itemFrame" id="itemContainer">
        <div class="listStyle" *ngFor="let item of list">{{item}}</div>
</div>

当我像这样使用colde时,它只返回Promise was not fullfilled。

但是,如果我尝试 itemList.children != undefined 并返回 .length,它将返回 0。我错过了什么?

提前致谢!

【问题讨论】:

  • 我认为由于其他一些异常,您会收到该错误。您能否在浏览器控制台中发布更多错误行?
  • 技术上我没有得到真正的“错误”,我只是得到了err 中的console.log,我从reject 得到了没有其他例外。但这对我来说毫无意义。它在 200 毫秒后加载,我已经检查了 dom 是否真的存在。
  • Object { __zone_symbol__error: Error, fileName: Getter, lineNumber: Getter, columnNumber: Getter, message: Getter, name: Getter, stack: Getter, originalStack: Getter, zoneAwareStack: Getter, toString: value( ),还有 3 个……}

标签: javascript html angular promise


【解决方案1】:

您可能想使用AfterViewInit。将局部变量 #itemContainer 添加到您的容器中:

<div class="itemFrame" id="itemContainer" #itemContainer>
    <div class="listStyle" *ngFor="let item of list">{{item}}</div>
</div>

然后在您的组件中,您可以检查子元素(或将元素传递给另一个检查它的函数):

import { ViewChild, ElementRef, AfterViewInit } from '@angular/core';

export class YourComponent implements AfterViewInit {
  @ViewChild('itemContainer') itemContainer: ElementRef;

  ngAfterViewInit() {
      if (this.itemContainer.nativeElement.children.length) {
          // ...
      } else {
          // ...
      }
  }
}

【讨论】:

  • 这确实解决了问题(我已经解决了这个问题,甚至加载了自己)但它没有回答我的问题,为什么我的第一个解决方案不起作用。还是谢谢
  • 关于您的第一个解决方案,也许您需要将代码包装在 setTimeout 中以确保它已呈现。
  • 这是我的第一个想法。但这是对 setTimeout 的一个非常糟糕的使用,因为较慢的机器可能需要更长的时间,然后超时或较快的机器可能会立即显示,但超时会阻止它们。
  • 嗯,我不确定除了在呈现最后一项时尝试执行一个函数之外你还能做什么:&lt;div *ngFor="let item of list; let last = last;"&gt;&lt;span *ngIf="last"&gt;{{ yourMethod() }}&lt;/span&gt;&lt;/div&gt;。但这会执行很多次,所以你必须确保你的函数在第一次之后才返回。
  • 那也行 :) 但我认为你错过了我的观点。我想了解我的问题。但我认为现在不应该使用这种解决方法。感谢弗兰克的帮助
【解决方案2】:

getElementById 返回单个元素,因为 id 应该是唯一的,而不是数组。其他查询确实返回和数组(例如getElementsByClassName 或getElementsByTagName)。

【讨论】:

  • 对不起,我简化了我的代码,以便人们可以理解它并使用了误导性的变量声明。列表中的内容是包含 *ngfor 元素的
    容器。
【解决方案3】:

你的处理程序写在哪里?它可能在视图初始化之前就被执行了。如果是这样,请尝试将其移至ngAfterViewInit

your.component.ts

import { AfterViewInit } from '@angular/core'
export class YourComponent implements AfterViewInit {

    ngAfterViewInit() {
        kistenPromise.then(...)

    }
}

【讨论】:

  • 我在 ngOnInit 中使用它。而且我不想使用诸如 window.ready 或事件加载之类的东西......在这种情况下,我什至不需要承诺。
猜你喜欢
  • 2017-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 1970-01-01
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多