Comenzando con la interoperabilidad con JavaScript
Un ejemplo básico del uso de APIs de navegador y una librería JS empaquetada.
Este tutorial te enseña los conceptos básicos de la interacción con JavaScript en código Dart utilizando varias APIs del navegador y de JavaScript.
Accede y define un objeto de JavaScript
#Para acceder a un objeto global de JavaScript, como el objeto
document del navegador, declara un getter de nivel superior anotado con @JS y externo (external).
Esto devuelve el valor como un JSObject opaco.
import 'dart:js_interop';
// All top-level JS interop APIs need the @JS annotation.
@JS()
external JSObject get document;
Un JSObject es opaco y no proporciona seguridad de tipos ni autocompletado de código.
Para agregar miembros con seguridad de tipos, define un tipo de interoperabilidad utilizando un extension type.
Esto actúa como una interfaz, permitiéndote declarar más APIs de interoperabilidad como
miembros externos (external). Puedes definir un tipo de interoperabilidad utilizando
extension types para visualizarlo de manera diferente:
@JS()
external Document get document;
extension type Document._(JSObject _) implements JSObject {}
Ahora, puedes agregar métodos externos a tu interfaz Document. Por ejemplo,
agrega el método de instancia createElement():
extension type Document._(JSObject _) implements JSObject {
external JSObject createElement(JSString tag);
}
Con el método createElement definido, puedes llamarlo en el
objeto document. Ten en cuenta que debes convertir 'button'
de
un String a un JSString usando el método de extensión .toJS.
var button = document.createElement('button'.toJS);
Los valores que se pasan hacia y desde las APIs de interoperabilidad deben ser un
tipo de interoperabilidad (como JSObject o JSString) o un tipo primitivo
permitido de Dart.
Usa conversiones automáticas de tipos
#El compilador convierte automáticamente la mayoría de los tipos primitivos de Dart
(como String, num, bool y null), por lo que a menudo puedes
usarlos directamente en las firmas de interoperabilidad para simplificar tu código.
Por ejemplo, puedes reescribir la declaración createElement
de la sección anterior para aceptar directamente un String de Dart.
Por ejemplo:
external JSObject createElement(String tag);
Ahora, puedes llamarlo sin la conversión explícita .toJS.
Por ejemplo:
var button = document.createElement('button');
Para agregar el botón recién creado al cuerpo (body) del documento, primero
define tipos de interoperabilidad para el body y su método
appendChild():
extension type Document._(JSObject _) implements JSObject {
external JSObject createElement(String tag);
external Body get body;
}
extension type Body._(JSObject _) implements JSObject {
external JSObject appendChild(JSObject child);
}
Con estas definiciones, puedes crear un botón y agregarlo a la página:
var button = document.createElement('button');
document.body.appendChild(button);
Maneja eventos y callbacks
#Para manejar las interacciones del usuario, como el clic de un botón,
puedes registrar un escucha de eventos utilizando addEventListener().
Primero, crea una interfaz para un elemento de botón. Luego, llama a
addEventListener con el nombre del evento y una función de callback.
extension type ButtonElement(JSObject _) implements JSObject {
external void addEventListener(String event, JSFunction listener);
}
var button = ButtonElement(document.createElement('button'));
document.body.appendChild(button);
button.addEventListener('click', (JSObject event) {
print('Clicked!');
}.toJS);
Los callbacks convertidos a JS con .toJS tienen las mismas
limitaciones de tipo que otras APIs de interoperabilidad, en el sentido de que sus parámetros
y valores de retorno deben ser tipos de interoperabilidad o primitivos compatibles.
Trabaja con Promesas (Promises) y Arrays
#La interoperabilidad con JavaScript proporciona ayudantes (helpers) para otros tipos comunes, como
la conversión de Promises de JavaScript hacia y desde Futures de Dart, y
Arrays hacia y desde Lists.
Promesas (Promises) y Futures
#Este ejemplo utiliza la API fetch, que devuelve una Promise.
La extensión .toDart convierte la Promise en un Future,
de modo que puedes usar await para esperar su resultado en Dart:
import 'dart:js_interop';
extension type Response._(JSObject _) implements JSObject {
external bool get ok;
}
@JS()
external Response fetch(String resource);
void main() async {
var response = await fetch('image.png').toDart;
print(response.ok);
}
Arrays y Listas (Lists)
#Este ejemplo llama al método estático Array.of de JavaScript
para crear un JSArray. Luego convierte el array a una
List de Dart, itera sobre ella e imprime cada elemento.
import 'dart:js_interop';
@JS('Array.of')
external JSArray<JSString> arrayOf(String a, String b);
void main() {
var array = arrayOf('hello', 'world');
var list = array.toDart;
for (var element in list) {
print(element.toDart);
}
}
Al convertir un tipo genérico como una List, sus elementos
ya deben ser tipos de JS interop. Por ejemplo, para convertir
una List<String>, primero debes convertir cada String
en un JSString.
// Option 1: Create the list with JS types initially.
List<JSString> list = ['hello'.toJS, 'world'.toJS];
JSArray jsArray1 = list.toJS;
// Option 2: Map a Dart list to a list of JS types.
List<String> dartList = ['hello', 'world'];
JSArray jsArray2 = dartList.map((e) => e.toJS).toList().toJS;
Más información
#- Para obtener más información sobre las conversiones de tipo, consulta Conversiones.
- Para obtener más información sobre cómo escribir APIs de interoperabilidad, consulta la Guía de uso.
-
To access common utility functions, see:
- La librería
dart:js_interop, y - La librería
dart:js_interop_unsafe.
- La librería
- El paquete
package:webexpone muchas de las APIs del navegador (incluyendo las utilizadas en los ejemplos anteriores) a través de declaraciones de interoperabilidad.
A menos que se indique lo contrario, la documentación en este sitio refleja Dart 3.12.2. Página actualizada por última vez el 2025-08-07. Ver fuente oreportar un problema.