2011-06-17 7 views
15

Estoy creando una aplicación de edición de mapas en la que podemos crear y editar polilíneas, polígonos, etc. Tengo algunos problemas para encontrar información sobre la implementación de deshacer en la web, me parece que lloro sobre "tenemos que deshacer" "y" aquí está mi patrón de comando utilizando cierres ", pero creo que entre eso y una interfaz completa para deshacer/rehacer hay bastante camino.Implementando deshacer en una aplicación web

lo tanto, aquí están mis preguntas (buen candidato para wiki creo):

  • En caso de que gestionar la pila, o hay una manera de enviar comandos a mis pila del navegador? (y cómo manejo comandos nativos, como ediciones de texto en textifields en este caso)
  • cómo manejo la "compresión de comandos" (agrupación de comandos) cuando algunos comandos son nativos del navegador
  • ¿Cómo puedo detectar el deshacer (ctrl + z) pulsación de tecla?
  • Si registro un evento de teclado, ¿cómo puedo decidir si impido o no?
  • Si no, ¿puedo registrar algún manejador de deshacer en alguna parte?
  • Los usuarios no se utilizan para deshacer en la web, ¿cómo puedo "entrenarlos" para explorar/deshacer en mi aplicación?

Gracias a todos.

+0

Deshacer qué? Los campos de entrada en el navegador tienen deshacer usando ctrl-z. ¿Qué necesitas deshacer? ¿Un envío? – mplungjan

+0

mi contexto es la creación de mapas, pero me gustaría abrir el tema un poco. – nraynaud

Respuesta

1

La manera en que funciona el soporte de deshacer automático de Cappuccino es decirle al administrador de deshacer qué propiedades deben deshacerse. Por ejemplo, pretender que es la gestión de los registros de los estudiantes, es posible hacer algo como:

[theUndoManager observeChangesForKeyPath:@"firstName" ofObject:theStudent]; 
[theUndoManager observeChangesForKeyPath:@"lastName" ofObject:theStudent]; 

Ahora, independientemente de cómo se cambia el nombre de los estudiantes en la interfaz de usuario, golpeando deshacer volverá automáticamente de nuevo. Cappuccino también maneja automáticamente los cambios coalescentes en el mismo ciclo de ejecución, marcando el documento como "sucio" (que necesita guardar) cuando hay elementos en la pila de deshacer, etc. (en otras palabras, lo anterior debe ser TODO lo que necesita hacer para apoyar deshacer).

Como otro ejemplo, si usted quiere hacer adiciones y supresiones de los estudiantes puede deshacer, que haría lo siguiente:

[theUndoManager observeChangesForKeyPath:@"students" ofObject:theClass]; 

Desde "estudiantes" es un conjunto de estudiantes en theClass, a continuación, adiciones y supresiones de esta matriz será rastreado.

+0

gracias, eso es interesante, pero ¿cómo se integra con el deshacer/rehacer nativo en el navegador? – nraynaud

+0

Cappuccino simplemente maneja eso - lo ata automáticamente en cmd-z en mac, y las ataduras de teclas apropiadas en ventanas, etc. etc. Todo debería "funcionar". –

+0

Mi objetivo no es usar cappuccino a ciegas, estoy creando un sistema ando para una aplicación que no usa cappuccino. Me gustaría entender cómo lo hiciste antes. Pero el código del framework es realmente difícil de leer y seguir para profanes. – nraynaud

10

Necesita tener funciones para la creación y eliminación de objetos. Luego pasa esas funciones al administrador de deshacer. Vea el archivo de demostración de mi administrador de deshacer de JavaScript: https://github.com/ArthurClemens/Javascript-Undo-Manager

El código de demostración muestra lienzo, pero el código es independiente.

No contiene enlaces de teclas, pero puede ayudarlo con los primeros pasos.

Yo mismo lo he usado en una aplicación web con botones para deshacer y rehacer, al lado de guardar.

+0

Está lejos de ser suficiente administrar estados de editor transitorios (como cuando se dibujó solo un punto de una polilínea y aún no el segundo), o acciones de edición continua que necesitan la compresión de la pila de deshacer (editor de color, control deslizante). – nraynaud

+0

De hecho, un enfoque genérico no funcionará en ese caso. Para acciones continuas puede elegir almacenar solo el resultado final. –

+0

el problema es detectar el "resultado final" como una propiedad directamente vinculada a un control deslizante (para que el usuario tenga comentarios inmediatos sobre su acción), no sabes cuándo ha terminado de manipular el control deslizante. Puedes intentar inferirlo con el tiempo (2s sin tocar el control deslizante significa que ha terminado) pero es complicado acertar, con algún evento (soltar el botón del mouse) en el control, simplemente comprime la pila de deshacer sobre la marcha (significa que tiene algunas cosas comparables en la pila, no cierres simples, o puede marcar grupos de eventos. – nraynaud

5

Aquí está una muestra de N niveles de deshacer usando Knockout JS:

http://jsfiddle.net/paultyng/TmvCs/22/

Se utiliza un modelo MVVM por lo que su estado de la página está representado en un objeto JavaScript que mantiene un historial de.

Cuestiones relacionadas