首页 > 解决方案 > 如何从 element.all each 返回一个元素

问题描述

我正在尝试从元素列表中返回一个元素,然后执行一些其他操作,例如单击、拖放等。我尝试了以下代码,但收到错误提示 nodes.click() not a function

var nodes = vectorpo.yfilesCanvasMain.all(
               by.css("g text[fill-opacity='1']")
            )
            .each(function (eachnode, index) {
               eachnode.getText().then(function (text) {
                 if (text == 'hello world') {
                   return eachnode;
                 }
               })
            });

nodes.click();

标签: javascriptprotractor

解决方案


根据您的问题陈述,您有兴趣过滤出元素数组,并希望对过滤后的元素列表执行一些操作。正如我所说的问题并正确理解,函数“每个”不适合这个,因为“每个”函数意味着迭代 ElementArrayFinder 对象的每个元素,因此在调用每个 elementFinder 后返回并解析 Promise。'each' 函数用于解决不同类型的问题。

那么,解决您提到的问题的正确方法是什么?

ElementArrayFinder 类还提供函数 'filter'。此函数用于过滤掉此元素列表。因此'filter' 函数不返回任何承诺,它在应用其中定义的过滤条件后返回 ElementArrayFinder 的对象。请参阅适用于您共享的代码的以下代码段。

vectorpo.yfilesCanvasMain.all(by.css("g text[fill-opacity='1']")).filter(eachNode, index){
 return eachNode.getText().then(function(text){
   return text === 'hello world';
    });
}).first().click();

first().click() 之前的代码将再次返回满足具有“hello world”文本的元素条件的 ElementArrayFinder 对象。这就是我们使用 first() 从 ElementArrayFinder 对象中获取第一个元素的原因。

ElementArrayFinder.each()只能返回null,如果你坚持使用each()归档你的目标,你可以这样做:

var found, node;

vectorpo.yfilesCanvasMain.all(
   by.css("g text[fill-opacity='1']")
)
.each(function (eachnode, index) {
    // if had found the wanted node, end this loop in advance
    if (found) return;

  eachnode.getText().then(function (text) {
        if (text == 'hello world') {
        node = eachnode; // assign wanted node to outside variable `node`
        found = true; // change flag: found to true
        }
    })
})
.then(function() {
  // the function inside this `then()` will only be executed when above `each()` complete
  // if the ouside variable is not null or undefined,
  // means find wanted node, then click
  if (node) node.click();
});

即使您可以通过 归档相同的目标each(),但它比 更复杂filter(),我建议使用filter()


推荐阅读