Saltar al contenido principal

Hacer que una pantalla reaccione

Objetivo​

Hacer que una pantalla dibujada haga algo: un encabezado que dice el nombre que alguien escribió, un recuadro que aparece cuando se marca una casilla, un botón Guardar que solo se activa cuando el formulario está rellenado.

Nada de eso es una imagen, y nada de eso es código que se escribe en un archivo. Es estado —el puñado de cosas que cambian mientras alguien usa la pantalla— y enlaces, que son expresiones de una línea que lo leen.

Paso 1: dar algo de estado a la pantalla​

  1. Abra la pantalla en el diseñador (Pantallas → seleccione una → Diseñar).
  2. Haga clic en el propio marco de la pantalla —el cuadro más exterior— y abra la pestaña Pantalla del inspector de la derecha.
  3. En Estado de la pantalla, pulse Agregar un campo de estado.
  4. Escriba un nombre —por ejemplo requester— y un valor inicial.

El valor inicial es una expresión, no un valor escrito sin más, así que un cuadro vacío empieza como "" (dos comillas), una casilla como false y un contador como 0. Es el mismo lenguaje que todo lo demás en esta pantalla, por eso solo hay una cosa que aprender.

Agregue tantos como necesite la pantalla. La mayoría de las pantallas necesitan dos o tres.

Por qué el estado vive en la pantalla

Porque dos controles leen el mismo campo. Si el estado perteneciera al cuadro desde el que se agregó, eliminar ese cuadro se llevaría el campo consigo, y todo lo demás que lo lee dejaría de funcionar sin avisar.

Paso 2: enlazar una propiedad​

  1. Seleccione cualquier objeto del lienzo.
  2. En la pestaña Pantalla, en Enlaces, elija una propiedad en Enlazar una propiedad.
  3. Aparece un editor con un ejemplo. Sustitúyalo por su expresión.

Se pueden enlazar cuatro propiedades:

PropiedadControlaEn
Textolo que dice: las palabras de un encabezado, la etiqueta de un botón, el texto de marcador de posición de un cuadrocualquier cosa
Se muestrasi está en la pantalla o nocualquier cosa
Habilitadosi un control se puede usarcontroles
Valorlo que contiene un controlcontroles

Todo lo demás de un objeto —dónde está, qué tamaño tiene, de qué color es— lo dibujó usted, y dibujar es la mejor forma de decir todo eso.

Ejemplos que hacen un trabajo real:

state.requester the Text of a heading
"Hello, " + state.requester the same, with words around it
state.showDetails the Shown of a panel
!state.showDetails the Shown of the line that says it is empty
state.requester != "" the Enabled of a Save button
screen.width > 700 the Shown of something a narrow window has no room for

El editor es el editor de BS Lang de la plataforma, así que subraya lo que no entiende y ofrece finalizaciones mientras escribe. Si aparece el subrayado, pase el puntero por encima para leer por qué.

Paso 3: dejar que un control escriba de vuelta​

Enlace el Valor de un cuadro de texto a state.requester, y escribir en él establece state.requester. Todo lo demás que lee ese campo lo sigue de inmediato: el saludo, el botón Guardar, todo.

Eso es todo lo que hace que una pantalla se sienta viva, y no necesita ningún controlador.

Una regla: la escritura de vuelta solo ocurre cuando el Valor es una ruta de estado simple: state.requester, o state.form.name. Si es calculado (state.first + " " + state.last), el control muestra el valor y es de solo lectura, porque no hay manera de deducir, a partir de lo que alguien escribió, los dos campos de los que procede.

Paso 4: hacer que ocurra algo al pulsar un botón​

  1. Seleccione el botón.
  2. En Cuando ocurra esto, elija Pulsado en Controlar un evento.
  3. Escriba lo que debe ocurrir, una instrucción por línea:
notify("Ticket raised for " + getState("requester"));
setState("requester", "");
setState("showDetails", false);

Lo que puede llamar un controlador:

LlamadaHace
setState("name", value)cambia el estado de la pantalla; todo lo que lo lee lo sigue
getState("name")lo vuelve a leer, para que pueda calcular a partir de lo que hay
loadRecords("table", "field")carga filas de una tabla en un campo de estado; consulte más abajo
getRecord("table", id, "field")carga un registro por su identificador
createRecord("table", { … }, "field")guarda un registro nuevo; el tercer argumento es opcional
updateRecord("table", id, { … })cambia los campos que nombre en un registro
deleteRecord("table", id)elimina un registro
callApi("GET", "psl/v1/overview", { … }, "field")pregunta a una Custom API y guarda su respuesta — vea Cifras de una Custom API
notify("…") / notifyError("…")avisa a la persona que usa la pantalla
showModal("Card") / closeModal()muestra una tarjeta superpuesta sobre la pantalla; consulte el paso 5
openStartDrawer("Card") / closeStartDrawer()desliza una desde el borde inicial
openEndDrawer("Card") / closeEndDrawer()y desde el borde final
openDropdown("Card") / closeDropdown()abre una junto a lo que se haya pulsado
setVisualState("name")pone en ese estado el objeto más cercano por encima de este controlador que tenga un estado dibujado; "" vuelve a Normal; consulte Reutilizar un diseño con componentes
openUrl("…", "newTab")va a una dirección web; omita el segundo argumento para quedarse en esta ventana
navigate("Screen")va a otra pantalla de esta aplicación, por el nombre de su marco
reloadSurfaces()vuelve a mostrar cada tabla o formulario integrado de esta pantalla, con datos nuevos

Un controlador es un pequeño programa, no una expresión. Puede cambiar cosas —para eso existe— y puede tener tantas líneas como necesite. Esa es la diferencia con un enlace, que solo lee.

Los demás eventos están ahí cuando los necesite: Pulsado dos veces, Valor cambiado (en un control), Recibe el foco, Pierde el foco, Llega el puntero, Sale el puntero y, en el propio marco de la pantalla, Se abre la pantalla, que se ejecuta una vez, después de que exista el estado.

Para cambiar solo el aspecto de algo, dibuje un estado

Un controlador que solo cambia el color de algo cuesta trabajo en cada movimiento del puntero. Un estado dibujado no cuesta nada en absoluto, porque lo hace el navegador. Consulte Reutilizar un diseño con componentes.

Ir a otra pantalla de la aplicación​

Una aplicación contiene varias pantallas, y navigate se mueve entre ellas:

navigate("Details");
navigate("Details", { id: getState("chosen") });

El nombre es el nombre del marco de la pantalla, exactamente como lo escribió ahí: cambie el nombre del marco y cada navigate que nombre el nombre antiguo deja de funcionar, algo que la pantalla le indica al pulsarlo en lugar de fallar sin avisar.

Qué sobrevive al cambio y qué no. La pantalla que deja se cierra: su estado desaparece, así que al volver obtiene uno nuevo; un formulario a medio rellenar no debería seguir a medio rellenar, y una pantalla que cargaba filas al llegar vuelve a cargarlas. Lo que viaja es lo que usted entrega: el segundo argumento llega como screen.params, así que screen.params.id en la pantalla siguiente lee lo que envió.

Siempre es screen.params. No existe un params más corto, y el editor de código lo subraya.

La barra de direcciones le sigue. Cada pantalla tiene su propia URL, así que el botón Atrás del navegador vuelve a la pantalla anterior, una recarga vuelve a la misma y un enlace que copie se abre ahí. Los valores entregados no viajan de esa forma —llegar con Atrás, recargando o con un enlace pegado abre la pantalla sin screen.params—, así que trátelos como una entrega entre dos pantallas y no como algo que pueda llevar un enlace.

Leer y escribir registros​

Cinco llamadas, y entre ellas son lo que convierte un dibujo en una aplicación.

Leer una lista:

loadRecords("par_ticket", "tickets");
loadRecords("par_ticket", "tickets", 20);
loadRecords("par_ticket", "tickets", { top: 20, where: { par_status: "Open" }, orderBy: "par_name" });

Las filas llegan al campo de estado que indicó, y todo lo demás de la pantalla ya sabe qué hacer con ellas: una tabla se repite sobre state.tickets, un rótulo lee state.tickets.length(). Consulte Dibuje una fila, obtenga una por registro.

El tercer argumento es o bien cuántas como máximo, o bien la pregunta completa: top, where, orderBy y descending. where solo compara por igualdad, y cada par que escriba tiene que coincidir. Cuando necesite más que eso —un intervalo, «contiene», un o—, construya una vista con el diseñador de consultas y dibuje la pantalla sobre ella en lugar de meterlo todo en una línea aquí.

Leer uno:

getRecord("par_ticket", screen.params.id, "ticket");

Es la pareja de navigate("Details", { id: row.id }): la pantalla de lista entrega el identificador, y la pantalla de detalles obtiene el registro que hay detrás. Si ese registro ya no existe, el campo se deja como estaba en lugar de vaciarse, así que los enlaces que dependen de él siguen funcionando.

Escribir:

createRecord("par_ticket", { par_name: getState("title"), par_status: "Open" });
createRecord("par_ticket", { par_name: getState("title") }, "created");
updateRecord("par_ticket", getState("ticket").id, { par_status: "Closed" });
deleteRecord("par_ticket", getState("ticket").id);

El tercer argumento de createRecord es opcional y a menudo merece la pena escribirlo: la plataforma responde con el registro que guardó, identificador incluido, así que getState("created").id es como la pantalla abre o actualiza después lo que acaba de crear. Sin él no hay forma de conocer ese identificador.

Los nombres de campo son los nombres lógicos de las columnas de la tabla —par_name, no Nombre—, los mismos que muestra el diseñador de tablas.

Diga algo después

Nada le indica a la persona que usa la pantalla que una escritura ha funcionado, así que dígalo usted: createRecord(…); notify("Ticket raised");. Si la plataforma rechaza la escritura —un campo obligatorio, un permiso—, la pantalla muestra el motivo que dio, por eso merece la pena leer el mensaje en lugar de sustituirlo. Y el resto de ese clic se detiene, así que un notify o un navigate después de la escritura solo ocurre si funcionó.

Lo que puede hacer una pantalla se decide en el servidor

Cada una de estas llamadas se comprueba contra los permisos de quien esté usando la aplicación, en cada llamada. Ocultar un botón Eliminar oculta un botón; no impide nada.

Para llevar a alguien a una página, dibuje un enlace

openUrl es para cuando la pantalla decide adónde ir: después de guardar, o según lo que se haya elegido. Cuando el destino simplemente se conoce, dibuje un enlace en su lugar: el clic central, el clic derecho → Abrir en una pestaña nueva y la lista de enlaces de un lector de pantalla funcionan en un enlace real y en nada más. Consulte Dibujar una aplicación de Studio.

Cifras de una Custom API​

Una cifra — las reservas de hoy, los ingresos de este mes — es un intervalo y una suma, a menudo sobre varias tablas, y loadRecords no puede pedirla. Calcúlela en una Custom API y llámela desde la pantalla:

callApi("GET", "psl/v1/overview", { date: "2026-10-06" }, "figures");

La dirección es la de la propia API dentro del entorno: su prefijo de editor, su versión y su ruta. Con GET las entradas viajan como cadena de consulta; con POST y los demás, como cuerpo. La respuesta llega al campo de estado que indique, así que un texto enlazado a state.figures.bookingsToday la muestra. La API se ejecuta con los permisos de quien usa la pantalla.

No en un portal

Una página de portal lee las tablas que su portal enumera y nunca nombra una API, así que allí callApi muestra un mensaje en lugar de una respuesta.

Cuando el cuadro se queda pequeño: la página de código​

Un enlace es una línea y pertenece junto a lo que controla. Un controlador crece, y después del tercer if el pequeño editor del panel es una ranura de buzón.

Seleccione primero el objeto y después pulse Escribir código en la barra de herramientas (el botón </>). El diseñador queda cubierto —la página a su alrededor se mantiene— por una lista de todo lo que se puede programar en ese objeto, en el lateral, y un editor con espacio para escribir. La lista contiene sus enlaces, sus controladores, los campos de estado de la pantalla y las propiedades propias de un componente. También aparecen los que están sin escribir, que es la respuesta más rápida a «¿qué podría poner en esto?».

La lista indica cuáles están escritos, así que nunca tiene que abrir uno para averiguarlo:

Junto al nombreSignifica
Un punto verde, nombre en negritaEscrito, y tiene sentido
Un punto rojo, nombre en negritaEscrito, y tiene un error: ábralo y el editor subraya dónde
Un punto hueco, nombre atenuadoTodavía no hay nada escrito

Mientras la página de código está abierta, el teclado es del editor. Escribir t escribe una t; no activa la herramienta Texto que hay detrás de la página.

Para volver, pulse Diseñar: el mismo botón que le devuelve de una vista previa, en el mismo sitio de la parte superior de la página. El dibujo está exactamente como lo dejó: la misma selección, el mismo zoom. Y es el mismo documento en ambos casos, así que un controlador escrito aquí aparece en el panel de allí.

Si no ocurre nada al pulsarlo, un mensaje explica por qué, y solo hay tres motivos:

El mensajeQué hacer
No hay nada seleccionado, o hay más de una cosaSeleccione exactamente un objeto
El código se escribe en el propio componenteTiene seleccionada una copia (una instancia) o una variante. Clic derecho → Ir al componente principal y escríbalo ahí: todas las copias lo reciben
Este objeto forma parte del gráfico de la pantallaIndique primero qué es en la pestaña Pantalla —un botón, un cuadro de texto— y entonces tendrá controladores que escribir

Un componente se escribe en su copia principal. Seleccione el marco del que está hecho el componente —no una copia en una pantalla— y la lista ofrece Pulsado y el resto, exactamente igual que para cualquier otra cosa. Ahí es donde pertenece el comportamiento de un componente: escríbalo una vez, y cada copia en cada pantalla lo hace.

Paso 5: preguntar antes de hacer algo, en un cuadro modal, una lista desplegable o un panel lateral​

Una tarjeta superpuesta es una parte de la pantalla que no está ahí hasta que un controlador la muestra.

  1. Dibuje su contenido una vez, como componente. Una tarjeta con una pregunta y dos botones es un componente como cualquier otro —consulte Reutilizar un diseño con componentes—, así que la misma confirmación puede usarse en cada pantalla que la necesite. Dibújela junto a su pantalla, donde haya espacio.

  2. Seleccione el componente y marque Una tarjeta superpuesta en la pestaña Gráfico. Esa es toda la configuración: deja de dibujarse en la pantalla y pasa a ser algo que un controlador puede mostrar.

  3. Muéstrela desde un controlador, por el nombre del propio componente:

    LlamadaDónde apareceÚtil para
    showModal("Confirm card")centrada sobre la pantalla, con un fondouna pregunta que hay que responder antes que nada
    openDropdown("Menu card")unida a lo que se pulsóun menú pequeño, una indicación, un formulario breve
    openStartDrawer("Filters card")a toda altura, deslizándose desde el borde inicialfiltros, un menú en una ventana estrecha
    openEndDrawer("Details card")a toda altura, desde el borde finalun panel de detalles
  4. Ciérrela con closeModal(), closeDropdown(), closeStartDrawer() o closeEndDrawer(); desde un botón dentro de ella, por ejemplo. Un panel lateral no tiene botón de cerrar propio: dibuje uno en la tarjeta, como hacen los menús de los ejemplos. Esc y un clic junto al panel lo siguen cerrando.

Una tarjeta que hay que responder​

Debajo de la marca Una tarjeta superpuesta hay una segunda: Hay que responderla. Con ella activada, hacer clic fuera de la tarjeta, pulsar Esc y el botón de cerrar dejan de funcionar mientras está abierta, y el botón de cerrar ni siquiera se muestra, porque un control que está visiblemente ahí y no hace nada parece una página congelada a quien lo pulsa dos veces.

Déjela desactivada salvo que la tarjeta pregunte algo que marcharse no puede responder. Una superposición que alguien abrió por accidente debe cerrarse igual que se abrió; el único tipo que no debe hacerlo es el que existe para obtener una respuesta —«¿eliminar estos cuatro registros?», «otra persona cambió este registro, ¿cuál conservar?»—, donde hacer clic en el fondo no es una respuesta y sin embargo lo parece.

Dibuje su propia salida. Una tarjeta obligatoria rechaza todas las formas de cerrarla que ofrece la plataforma, así que necesita un botón propio que ejecute closeModal(), closeStartDrawer() o closeEndDrawer(). Póngalo primero y sin énfasis, como un Cancelar junto a un Eliminar.

Una lista desplegable la ignora. Un menú que no se puede cerrar haciendo clic fuera ha atrapado la página, y una lista desplegable nunca es la forma de hacer una pregunta.

Una lista desplegable se abre junto a lo que ejecutó el controlador. No hay nada que elegir: ponga openDropdown("Menu card") en el botón, y el menú aparece junto a ese botón.

Dónde respecto a él, lo puede indicar: openDropdown("Menu card", "bottom-end"):

UbicaciónDónde va la tarjeta
"bottom" (el valor predeterminado)debajo del botón, centrada en él
"bottom-start" / "bottom-end"debajo, alineada con su borde inicial / final
"top", "top-start", "top-end"encima: para un control cerca de la parte inferior de una pantalla

end, no right. Una tarjeta abierta con bottom-end cuelga del borde derecho del botón en inglés y de su borde izquierdo en persa y árabe, que es la misma regla que siguen los paneles laterales: un solo script pone el menú en el lado correcto en todos los idiomas. Escribir "bottom-right" daría una pantalla al revés en persa sin nada que lo advirtiera; por eso no es una ubicación, y a un controlador que la pida se le avisa.

Está expresando una preferencia, no una promesa: si no hay espacio debajo, el menú se abre encima de todos modos. Un menú que se sale de la pantalla es peor que un menú en el otro lado.

Su ancho es el ancho con el que la dibujó. El ancho propio de la tarjeta es el ancho del panel lateral y el del cuadro modal, así que haga la tarjeta del tamaño que quiera que tenga el panel.

Hay uno de cada, y mostrar una segunda tarjeta sustituye a la primera. Una pantalla solo puede tener un cuadro modal abierto a la vez, por eso no hay nada que declarar: los contenedores siempre están ahí y su controlador dice qué va en uno.

El borde de un panel lateral sigue al idioma, no al dibujo. Inicial es la izquierda para quien lee en inglés y la derecha para quien lee en persa o árabe: toda la pantalla se refleja, porque en una aplicación lo que usted dibujó es el marco.

Esc, el fondo y un clic fuera cierran todos una superposición, y el foco vuelve a lo que la abrió. Nada de eso es algo que usted configure.

Paso 6: obtener una vista previa​

Pulse Vista previa. La vista previa es el tiempo de ejecución real —el mismo componente que monta el Shell, no una aproximación—, así que lo que ve es lo que ve alguien que usa la aplicación.

Escriba en los cuadros. Observe cómo le sigue el resto de la pantalla.

Reglas que conviene conocer​

Un enlace solo lee. Se vuelve a ejecutar cada vez que cambia lo que lee, así que un enlace que cambiara algo se reiniciaría continuamente. El diseñador lo rechaza al Guardar y le indica qué objeto y qué propiedad: todo lo que cambia algo pertenece a un controlador.

«Se muestra» quita, no oculta. Un elemento cuyo Se muestra es falso no está en la página en absoluto: nada llega a él con el tabulador, ningún lector de pantalla lo anuncia y Ctrl+F no lo encuentra. Casi siempre es lo que quería decir.

Nada de esto es seguridad. Un botón oculto es un botón oculto. Lo que una persona puede hacer realmente se decide en el servidor, cada vez, muestre lo que muestre la pantalla.

Lo que puede ver un enlace, hoy​

NombreEs
stateel propio estado de la pantalla, del paso 1
screenscreen.width y screen.height —la superficie, para que una pantalla pueda reaccionar a una ventana estrecha— y screen.name, la pantalla en la que está, para que una barra colocada en todas las pantallas pueda marcar su propia página
uiui.theme (light o dark), ui.locale (en, fa, ar) y ui.dir (ltr o rtl): los propios ajustes del lector
userquién ha iniciado sesión: user.name, user.email y user.photo (vacío si no tiene foto, así que vincule el Shown de una imagen a user.photo != ""): suficiente para un saludo o una barra superior, y a propósito sin sus roles
screen.paramslo que entregó la pantalla que le envió aquí: navigate("Details", { id })

Los registros llegan a través de un controlador, no mediante un nombre propio. loadRecords y getRecord los ponen en el propio estado de la pantalla, así que un enlace lee state.tickets como cualquier otra cosa: no hay un segundo sitio donde mirar. Lo que de verdad todavía no está aquí son las vistas guardadas de la plataforma: una pantalla nombra una tabla y un where, no una vista.

Lo que puede calcular un enlace​

Un enlace es una expresión, así que no puede hacer bucles ni llamar a setState. Unas pocas funciones pequeñas cubren lo que suele necesitar un rótulo además de la aritmética:

FunciónResponde
text(value)el valor como palabras, para que un número pueda ir dentro de una frase: "of " + text(state.total)
num(value)las palabras como número: lo que devuelve una lista desplegable, listo para la aritmética; 0 si no es un número
first(list, { field: value, … })la primera fila de una lista cargada cuyos campos contienen esos valores, o null: first(state.budgets, { par_department: state.department, par_category: state.category })
format(value, "integer" | "number" | "percent")un número tal como lo escribe su idioma: format(174500, "integer") es 174,500 en inglés y usa dígitos persas en persa
translate({ en: "…", fa: "…", ar: "…" })las palabras en el idioma del lector, con el inglés como alternativa; consulte Dos idiomas

first es como un rótulo sigue a un selector hasta la fila que nombra. Cargue la tabla una vez, en Se abre la pantalla; después "Available: £" + format(first(state.budgets, { … }).par_remainingbudget, "integer") sigue a dos listas desplegables vayan donde vayan, sin ningún controlador. Una fila cargada lleva una columna de opción como su etiqueta, y una lista desplegable devuelve la etiqueta que ofreció, así que las dos coinciden. Proteja el caso en que nada coincide con un condicional —first(…) == null ? "Choose a line" : …—, porque leer un campo de null hace fallar el enlace, y && no lo protege: los dos lados de un && se evalúan siempre.

Un intervalo es trabajo de un controlador. first compara valores exactos; «el tramo cuyo mínimo y máximo engloban este importe» es un bucle, y un bucle pertenece al controlador Valor cambiado del control, que escribe lo que encontró en el estado para que lo lea el rótulo. El ejemplo studio-capital-planning de samples/solutions hace las dos cosas en una pantalla.

Dos idiomas en una pantalla​

Enlace el Texto de un texto a translate(...), con cada idioma junto al inglés:

translate({ en: "Opening times", fa: "ساعات کار" })

y dé a la página un botón que cambie: if (ui.locale == "fa") { setLanguage("en"); } else { setLanguage("fa"); }. setLanguage cambia el idioma de la plataforma, no solo el de la pantalla: se recuerda, y en persa o árabe toda la página se refleja, porque cada posición que dibuja una pantalla es inicial y final y no izquierda y derecha. ui.dir indica en qué dirección se lee, para que una flecha pueda apuntar hacia el lado correcto.

Un idioma que el objeto no tiene recurre al inglés, así que una página a medio traducir se lee en inglés y no con huecos. El ejemplo portal-pages-and-navigation está escrito así, palabra por palabra.

Algo que ocurre por sí solo: el temporizador​

Dé a un objeto un controlador Tic del temporizador y enlace su Intervalo del temporizador (ms): ejecuta ese controlador cada tantos milisegundos mientras el objeto está en la página:

Timer interval (ms): state.held ? 0 : 5000
Timer ticks: setState("slide", (getState("slide") + 1) % 3);

Cero, o nada, es detenido, así que pausar forma parte del enlace, y un carrusel que se detiene mientras lo señala establece held en sus controladores Llega el puntero y Sale el puntero. Menos de 250 se sube a 250. Un objeto oculto no hace tic. El carrusel de la biblioteca de componentes, y el de la página de inicio de portal-pages-and-navigation, están construidos así.

Solución de problemas​

  • «No se pudo ejecutar un enlace en …» — la expresión es válida, pero algo que nombra no está. La causa más habitual es un campo de estado escrito de forma distinta en el enlace: compruebe la lista Estado de la pantalla del marco de la pantalla.
  • El cuadro no me deja escribir. — su Valor es una expresión calculada, así que es de solo lectura por diseño. Enlácelo a un campo de estado simple y calcule la otra cosa en otro sitio.
  • No ocurre nada al escribir. — el cuadro no tiene enlace de Valor. Un cuadro sin enlace se queda con lo que se escribe y no se lo dice a nadie.
  • El botón Guardar nunca se activa. — compruebe su expresión Habilitado con un valor vacío: state.requester != "" solo es verdadero cuando se ha escrito algo.
  • Pulsar el botón no hace nada. — un control deshabilitado no recibe ninguna pulsación, así que compruebe primero su enlace Habilitado; después compruebe que el controlador está en Pulsado y no en un evento que aquí nunca se dispara (Se abre la pantalla pertenece al marco de la pantalla, Valor cambiado a un control).
  • «No se pudo ejecutar un controlador en …» — el controlador es BS Lang válido, pero algo que nombra no está. La causa más habitual es setState en un campo que la pantalla nunca declaró.
  • «createRecord("…") falló: …» — la plataforma rechazó la escritura, y lo que sigue a los dos puntos es su propio motivo: un campo obligatorio sin nada, un valor que no es una de las opciones o un permiso que usted no tiene. Compruebe primero los nombres de campo con el diseñador de tablas: un nombre lógico mal escrito es la causa más habitual.
  • No se carga nada, y nada se queja. — está en Vista previa, que no tiene ningún entorno detrás. Las llamadas a registros no hacen nada ahí, a propósito. Abra la aplicación desde el Shell para ver registros reales.
  • showModal("…") no hace nada. — el nombre tiene que coincidir exactamente con el nombre del componente, y el componente tiene que tener marcada Una tarjeta superpuesta. Una tarjeta que se eliminó, o a la que se cambió el nombre, deja controladores que la nombran, y estos no hacen nada sin avisar en lugar de romper la pantalla.
  • La tarjeta se muestra en la pantalla en lugar de en un cuadro modal. — Una tarjeta superpuesta no está marcada. Hasta que lo esté, el componente se dibuja donde lo puso, como cualquier otro componente.
  • «Dos componentes se llaman …» — una tarjeta se muestra por el nombre de su componente, así que dos que compartan nombre son una pregunta que showModal no puede responder. Cambie el nombre de uno.

Pruébelo​

Importe la solución de ejemplo Ticket Triage. Es esta página, ya construida: tres campos de estado, propiedades enlazadas por todas partes, un estado al que el propio ejemplo dio nombre, un cuadro modal que pregunta antes de plantear la incidencia y un elemento emergente que se abre desde su propio botón.