2016-05-28 2 views
3

Ich versuche ein Array eines benutzerdefinierten Objekts zu erstellen, das einen ElementFinder als Parameter benötigt.Wie man .each oder .map verwendet, um mehrere Objekte im Winkelmesser zu erstellen

Das benutzerdefinierte Objekt StatusObj übernimmt ein ElementFinder-Objekt.

Der Code Ich versuche, meine Aufgaben zu tun erstellen und zurückgeben, dass Array wie folgt aussieht:

function getStatusObjs() { 
    var arr; 

    arr = $$('li').each(function(el) { 
     return new StatusObj(el); 
    } 

    return arr; 
} 

Dies funktioniert nicht. Es stürzt ab und die Zeit läuft aus oder der Speicherplatz wird knapp. Ich habe versucht ".map()" und ich habe versucht arr = new StatusObj(el); setzen, aber natürlich ist arr nicht in Geltungsbereich (aus Mangel an einem besseren Begriff) innerhalb der .each-Funktion.

Update für Alexce:

Hier ist der Stack-Trace ich, wenn ich Ihre Lösung versuchen:

<--- Last few GCs ---> 

    118309 ms: Mark-sweep 1254.4 (1434.1) -> 1239.4 (1434.1) MB, 2124.7/0 ms [allocation failure] [GC in old space requested]. 
    120614 ms: Mark-sweep 1239.4 (1434.1) -> 1239.4 (1434.1) MB, 2305.0/0 ms [allocation failure] [GC in old space requested]. 
    122702 ms: Mark-sweep 1239.4 (1434.1) -> 1239.4 (1434.1) MB, 2088.9/0 ms [last resort gc]. 
    124818 ms: Mark-sweep 1239.4 (1434.1) -> 1239.4 (1434.1) MB, 2115.1/0 ms [last resort gc]. 


<--- JS stacktrace ---> 

==== JS stack trace ========================================= 

Security context: 0x30c99fec9fa9 <JS Object> 
    1: get stack [native messages.js:595] [pc=0x32edf1d73957] (this=0x82e2251cb1 <a RangeError with map 0x206aaf5b8ae9>) 
    3: resolve_ [/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:1115] [pc=0x32edf1dfdbe5] (this=0x82e2247b99 <a Promise with map 0x206aaf58ff81>,newState=0x29909e1edd89 <String[8]: rejected>,newValue=0x82e2251cb1 <a RangeError with map 0... 

FAbort trap: 6 

Ist das ein Problem mit meinem Objekterstellung Code oder dass ich das Versprechen nicht Handling korrekt?

Antwort

1

Zur Zeit ist Fehler gemeldet für diese - https://github.com/angular/protractor/issues/2227

Ich habe schmutzige Hack das funktioniert für mich, während ich darauf warte, dass der Fehler behoben wird.

class ArrayContainer { 
    /** 
    * Special wrapper around array element finder, 
    * but wraps returned elements to provided classToWrap. 
    * 
    * TODO: Find way to wrap elements with $$('div').map(elem => new WrappedElem(elem)) 
    * Currently bug is reported - https://github.com/angular/protractor/issues/2227 
    * @param arrayFinder 
    * @param classToWrap 
    */ 
    constructor (arrayFinder, classToWrap) { 
     this.classToWrap = classToWrap; 
     this.arrayFinder = arrayFinder; 
    } 

    get(index) { 
     return new this.classToWrap(this.arrayFinder.get(index), this.arrayFinder.ptor_); 
    } 

    first() { 
     return new this.classToWrap(this.arrayFinder.first(), this.arrayFinder.ptor_); 
    } 

    last() { 
     return new this.classToWrap(this.arrayFinder.last(), this.arrayFinder.ptor_); 
    } 

    /** 
    * Wraps .map() function, so provided function will receive wrapped object as first param, not ElementFinder. 
    */ 
    map(func) { 
     return this.arrayFinder.map((elem, index) => { 
      // No return, since i am not sure that it will not fail with this bug - 
      // https://github.com/angular/protractor/issues/2227 
      func(new this.classToWrap(elem, this.arrayFinder.ptor_), index) 
     }); 
    } 
    /** 
    * Wraps .filter() function, so provided function will receive wrapped object as first param, not ElementFinder. 
    */ 
    filter(func) { 
     let filtered = this.arrayFinder.filter((elem, index) => { 
      return func(new this.classToWrap(elem, this.arrayFinder.ptor_), index) 
     }); 
     return new ArrayContainer(filtered, this.classToWrap); 
    } 

    count() { 
     return this.arrayFinder.count(); 
    } 
} 

Hinweis .map() Funktion gibt nichts in meinem Hack

Verwendung ist -

var checkboxes = ArrayContainer($$('.checkbox'), Checkbox); 
checkboxes.first() // returns Checkbox object, not ElementFinder 
2

Sie benötigen die map():

function getStatusObjs() { 
    return $$('li').map(function(el) { 
     return new StatusObj(el); 
    }); 
} 

Nun wäre das Ergebnis getStatusObjs() Anruf ein Versprechen sein, das in einer Reihe von StatusObj Objekte aufgelöst werden würde:

getStatusObjs().then(function (objs) { 
    console.log(objs); 
}); 
+0

Ich bin ein Auslöser Range bekommen. Ich habe meine Frage mit dem Fehler aktualisiert. Ich habe überprüft, dass meine Auswahl korrekt ist. '$$ ('li'). count()' gibt einen Wert von 2 zurück. – Machtyn

+1

@Machtyn Okay, klingt wie etwas, das innerhalb des 'StatusObj'-Codes passiert, den du nicht angezeigt hast. – alecxe

Verwandte Themen