2012-11-13 23 views
11

Abbiamo visto il termine "Expando" usato di recente con Dart. Sembra interessante. L'API non mi ha fornito molti indizi.A cosa serve la funzione "Expando" di Dart, che cosa fa?

Un esempio o due potrebbero essere più utili!

(Non sono sicuro se questo è correlato, ma sono molto ansioso per un modo di aggiungere metodi (getter) e/o variabili a una classe. Sperare che questo potrebbe essere una chiave per risolvere questo problema. utilizzando il metodo Nosuchmethod ora e voglio essere in grado di restituire il valore del metodo non trovata.))

Grazie in anticipo,

_swarmii

risposta

10

Expandos permettono di associare gli oggetti ad altri oggetti. Un esempio molto utile di questo è un elemento DOM HTML, che non può essere sottoclassificato. Facciamo un Expando di alto livello per aggiungere alcune funzionalità di un elemento - in questo caso una firma funzione data nella dichiarazione typedef:

typedef CustomFunction(int foo, String bar); 

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

Ora per usarlo:

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

Cosa c'è di diverso tra questo e Mappa ? –

1

Ci ho giocato un po '. Ecco cosa ho.

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

Il giorno in cui annuncio questo, la versione di Dart è r19425 –

4

Giusto per chiarire la differenza tra expando e le mappe: come riportato nel groups, expando ha riferimenti deboli.
Ciò significa che una chiave può essere raccolta dati inutili anche se è ancora presente nel expando (purché non ci siano altri riferimenti ad essa).

Per tutti gli altri scopi è una mappa.