Redirigir y decir qué pasó
Traducción automática
Esta página se tradujo automáticamente del inglés y todavía no la revisó un hablante nativo; las correcciones son bienvenidas en GitHub. Si algo no coincide, vale el original en inglés.
Tarea: después de enviar un formulario, llevar al navegador a una página y decirle qué pasó, una sola vez.
yaml
# Recipe: after a POST, send the browser to a page and tell it what happened.
paths:
components: ./components
migrations: ./migrations
datasources:
db:
driver: sqlite
database: ./data/notes.dbsql
CREATE TABLE notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
text TEXT NOT NULL,
done INTEGER NOT NULL DEFAULT 0
);q:redirect termina la acción. Su flash acepta expresiones y se convierte en flash en la siguiente página que se renderiza, con flashType en success. Para otro tipo de mensaje, q:flash type="warning" define ambos antes de la redirección. La URL puede ser cualquier página de la aplicación.
xml
<q:component name="Notes">
<q:action name="add" method="POST">
<q:param name="text" required="true" maxlength="200" />
<q:query name="added" datasource="db">
INSERT INTO notes (text) VALUES (:text)
<q:param name="text" value="{text}" type="string" />
</q:query>
<!-- The flash accepts expressions; its type is "success". -->
<q:redirect url="/" flash="Added: {text}" />
</q:action>
<q:action name="clear" method="POST">
<q:query name="finished" datasource="db">
UPDATE notes SET done = 1 WHERE done = 0
</q:query>
<q:if condition="finished_result.recordCount == 0">
<!-- A flash of another kind: q:flash sets both, the redirect keeps them. -->
<q:flash type="warning">There was nothing to clear.</q:flash>
<q:redirect url="/" />
</q:if>
<q:redirect url="/done" flash="Cleared {finished_result.recordCount} notes." />
</q:action>
<q:query name="notes" datasource="db">
SELECT id, text FROM notes WHERE done = 0 ORDER BY id
</q:query>
<ui:window title="Notes">
<!-- flash and flashType exist on every page, '' when there is none;
a flash shows on the next page rendered, once. -->
<q:if condition="flash">
<ui:alert variant="{flashType}">{flash}</ui:alert>
</q:if>
<ui:form on-submit="add">
<ui:hbox gap="sm">
<ui:input bind="text" placeholder="A note" grow="true" />
<ui:button variant="primary">Add</ui:button>
</ui:hbox>
</ui:form>
<q:loop query="notes">
<ui:text>{notes.text}</ui:text>
</q:loop>
<ui:button on-click="clear">Clear all</ui:button>
</ui:window>
</q:component>xml
<q:component name="Done">
<ui:window title="All clear">
<q:if condition="flash">
<ui:alert variant="{flashType}">{flash}</ui:alert>
</q:if>
<ui:link to="/">Back to the notes</ui:link>
</ui:window>
</q:component>La segunda prueba abre la página de nuevo después de la redirección: el mensaje flash ya no está, y flash es ''.
xml
<q:test name="adding a note redirects back with a success flash" page="/">
<test:submit action="add" text="Buy bread" />
<test:expect status="302" redirect="/" flash="Added: Buy bread" />
<test:expect var="flashType" value="success" />
<test:expect text="Buy bread" />
</q:test>
<q:test name="the flash shows once" page="/">
<test:submit action="add" text="Buy bread" />
<test:expect text="Added: Buy bread" />
<test:visit />
<test:expect no-text="Added: Buy bread" />
<test:expect var="flash" value="" />
</q:test>
<q:test name="clearing sends the browser to another page" page="/">
<test:given table="notes" text="Buy bread" />
<test:given table="notes" text="Call Ana" />
<test:submit action="clear" />
<test:expect redirect="/done" flash="Cleared 2 notes." />
<test:expect text="All clear" />
<test:expect table="notes" count="0" where="done = 0" />
</q:test>
<q:test name="nothing to clear is a warning, on the same page" page="/">
<test:submit action="clear" />
<test:expect redirect="/" flash="There was nothing to clear." />
<test:expect var="flashType" value="warning" />
</q:test>text
tests/notes.test.q
PASS adding a note redirects back with a success flash
PASS the flash shows once
PASS clearing sends the browser to another page
PASS nothing to clear is a warning, on the same page
4 passed, 0 failedVer ACT-3.