2015-08-28 3 views
3

Скажем, у меня есть следующая структура DOM, для простоты:Intern:.. Петля на Promise <Массив <Лэдфут/Элемент >>

<div class='myparent'> 
    <div class='child'> 
     <div class="label">A</div> 
     <div class="ico"/> 
    </div> 
    <div class='child'> 
     <div class="label">B</div> 
     <div class="ico"/> 
    </div> 
    <div class='child'> 
     <div class="label">C</div> 
     <div class="ico"/> 
    </div> 
</div> 

Я хотел бы цикл в течение всего child элемента, возвращаемого функцией findAllByCssSelector ('. ребенок). В частности, я хотел бы нажать на ico сНу подэлементе ТОЛЬКО если label из DIV является B.

Я помню, что findAllByCssSelector() возвращается Promise.<Array.<leadfoot/Element>>.

Обычно я должен сделать что-то вроде:

var my_label = null; 
this.remote 
    .findAllByCssSelector('.my-selector').then(function (elementArray) { 
     for(.....) { 
     elementArray[i] 
      .getVisibileText() 
       .then(function (text) { 
        if(text == my_label) 
        elementArray[i].findByCssSelector('.ico').click().end() 
       } 
     } 
}) 

Я попробовал этот код, но не работает, потому что elementArray[i] внутри функции getVisibleText().then() не существует - это как я теряю свою ссылку. Кроме того, мне также нужно, чтобы, если метка не найдена в конце цикла, должно быть выбрано исключение.

Как я могу это достичь? Может ли кто-нибудь помочь, пожалуйста?

+0

Итак? Просто поместите цикл в ответный вызов. Вы знаете, как получить доступ к массиву? Пожалуйста, опубликуйте свою текущую попытку кода (даже если она не работает) – Bergi

ответ

4

Самый простой способ сделать это было бы использовать выражение Xpath, чтобы выбрать пункт непосредственно, как:

.findByXpath('//div[@class="child" and div[@class="label" and text()="B"]]/div[@class="ico"]') 

Выражение выше будет найти первый DIV с классом «ICO», что это ребенок div с классом «child», который имеет дочерний div с классом «label» и текстовым контентом «B».


Update

Используя выражение Xpath почти всегда предпочтительнее циклически элементов с помощью команд Лэдфут, потому что это значительно более эффективным, но если цикл желательно по какой-то причине, вы можете сделать что-то вроде:

var my_label = null; 
this.remote 
    .findAllByCssSelector('.my-selector') 
    .then(function (elementArray) { 
     return Promise.all(elementArray.map(function (element) { 
      return element.getVisibleText() 
       .then(function (text) { 
        if (text === my_label) { 
         return element.findByCssSelector('.ico') 
          .then(function (ico) { 
           return ico.click(); 
          }); 
        } 
       }); 
     }); 
    }); 

несколько ключевых моментов, чтобы отметить:

  1. Вы должны вернуть Promises/Команды из then обратных вызовов, когда вы выполняете операции асинхронных в then обратных вызовах
  2. методы Element (как element.findByCssSelector) возвращение Promises, а не команды, так что вы не можете вызвать click на результате.
+0

К сожалению, 'ico' и' label' divs являются братьями и сестрами, как показано выше. Кроме того, я бы сказал, что вышеприведенный фрагмент действительно упрощен, так как между 'child' и' labe | ico' может быть больше div. Однако спасибо за усилия. Кстати, здесь вопрос заключается в том, как зацикливаться на 'Promise. >' и сохранять след элемента, если проверяется определенное условие. Я обновляю первый пост, чтобы лучше объяснить себя. –

+0

Вышеприведенный выше оператор Xpath предполагает, что деления 'ico' и' label' являются братьями и сестрами - вот в чем смысл. Он работает с фрагментом, предоставленным в вопросе, и может быть легко модифицирован для обработки более сложной структуры. – jason0x43

+0

@ jason0x43 извините, не прошел ваш ответ правильно, после того как я отредактировал свой ответ, чтобы использовать «карту», ​​стал вашим дубликатом, поэтому удалил мой :) – mido