2012-11-13 6 views
11

Habe den Begriff "Expando" kürzlich bei Dart verwendet. Hört sich interessant an. Die API hat mir nicht viel Ahnung gegeben.Worum geht es bei Dart "Expando", was macht es?

Ein oder zwei Beispiele könnten sehr hilfreich sein!

(Nicht sicher, ob das verwandt ist, aber ich bin sehr gespannt auf eine Möglichkeit, Methoden (Getter) und/oder Variablen zu einer Klasse hinzuzufügen.Hoffnung dies könnte ein Schlüssel zur Lösung dieses Problems sein (Hinweis: Ich bin die Nosuchmethod Methode jetzt und will in der Lage, den Wert der unfound Methode zurückzukehren.))

Vielen Dank im Voraus,

_swarmii

Antwort

10

Expandos kann Sie Objekte mit anderen Objekten verknüpfen. Ein sehr nützliches Beispiel hierfür ist ein HTML-DOM-Element, das selbst nicht unterklassifiziert werden kann. Lassen Sie uns ein Top-Level-expando machen einige Funktionen zu einem Element hinzuzufügen - in diesem Fall eine Funktion Signatur in der typedef-Anweisung gegeben:

typedef CustomFunction(int foo, String bar); 

Expando<CustomFunction> domFunctionExpando = new Expando<CustomFunction>(); 

Nun, es zu benutzen:

main(){ 
    // Assumes dart:html is imported 
    final myElement = new DivElement(); 

    // Use the expando on our DOM element. 
    domFunctionExpando[myElement] = someFunc; 

    // Now that we've "attached" the function to our object, 
    // we can call it like so: 
    domFunctionExpando[myElement](42, 'expandos are cool'); 
} 

void someFunc(int foo, String bar){ 
    print('Hello. $foo $bar'); 
} 
+7

Was unterscheidet dies von Map ? –

1

Ich habe ein bisschen damit gespielt. Hier ist, was ich habe.

import 'dart:html'; 

const String cHidden = 'hidden'; 

class ExpandoElement { 
    static final Expando<ExpandoElement> expando = 
     new Expando<ExpandoElement>("ExpandoElement.expando"); 

    final Element element; 

    const ExpandoElement._expand(this.element); 

    static Element expand(Element element) { 
    if (expando[element] == null) 
     expando[element] = new ExpandoElement._expand(element); 
    return element; 
    } 

// bool get hidden => element.hidden; // commented out to test noSuchMethod() 
    void set hidden(bool hidden) { 
    if (element.hidden = hidden) 
     element.classes.add(cHidden); 
    else 
     element.classes.remove(cHidden); 
    } 

    noSuchMethod(InvocationMirror invocation) => invocation.invokeOn(element); 
} 
final Expando<ExpandoElement> x = ExpandoElement.expando; 
Element xquery(String selector) => ExpandoElement.expand(query(selector)); 

final Element input = xquery('#input'); 

void main() { 
    input.classes.remove(cHidden); 
    assert(!input.classes.contains(cHidden)); 

    input.hidden = true; 
    assert(x[input].hidden); // Dart Editor warning here, but it's still true 
    assert(!input.classes.contains(cHidden)); // no effect 

    input.hidden = false; 
    assert(!x[input].hidden); // same warning, but we'll get input.hidden via noSuchMethod() 
    assert(!input.classes.contains(cHidden)); 

    x[input].hidden = true; 
    assert(input.hidden); // set by the setter of ExpandoElement.hidden 
    assert(input.classes.contains(cHidden)); // added by the setter 
    assert(x[input].hidden); 
    assert(x[input].classes.contains(cHidden)); // this is input.classes 

    x[input].hidden = false; 
    assert(!input.hidden); // set by the setter 
    assert(!input.classes.contains(cHidden)); // removed by the setter 
    assert(!x[input].hidden); 
    assert(!x[input].classes.contains(cHidden)); 

    // confused? 
    assert(input is Element); 
    assert(x[input] is! Element); // is not 
    assert(x[input] is ExpandoElement); 
    assert(x is Expando<ExpandoElement>); 
} 
+0

An dem Tag, an dem ich dies poste, ist die Dart-Version r19425 –

4

einfach den Unterschied zwischen expando und Karten zu klären: wie in der groups berichtet, expando hat schwache Referenzen.
Dies bedeutet, dass ein Schlüssel als Garbage Collection erfasst werden kann, auch wenn er noch in Expando vorhanden ist (sofern keine anderen Referenzen darauf vorhanden sind).

Für alle anderen Absichten und Zwecke ist es eine Karte.