2008-10-14 8 views
7

Estoy trabajando en un sistema donde un usuario puede editar objetos existentes (objetos de dominio "Filtrar" para ser exactos) a través de una GUI. Como sugerencia de UI, solo queremos habilitar el botón de guardar si el usuario realmente modificó algo al objeto. Me preguntaba si alguien tenía alguna experiencia con este problema y cuál sería la mejor manera de abordarlo.edición de objetos y bandera isDirty()

Estaba pensando en agregar una bandera isDirty() al objeto de dominio. Cuando un usuario comienza a editar un filtro, yo hago una copia, la paso a la GUI y le dejo al usuario modificaciones en la copia. Un enlace en el indicador isDirty() activaría/desactivaría el botón de guardar. Al guardar, las diferencias se fusionarían en el objeto original y se mantendrían.

Además, estaba pensando qué pasaría si un usuario deshace los cambios que hizo a un objeto. El indicador isDirty() debería devolver falso. Así que supongo que la única forma de lograr esto es mantener el valor original de cada propiedad dentro del objeto de dominio.

¿Alguna idea?

Respuesta

3

¡Correcto!

Además, puede exponer dos métodos: BeginEdit - En este método, marque su bandera IsDirty a True. Lo que significa que estás haciendo modificaciones. Llame a este método cuando esté a punto de hacer modificaciones

CancelEdit - En este método, restablezca la bandera IsDirty a False. Lo que significa que ha cambiado el proceso de edición y ha vuelto al estado original. Llame a este método cuando cancela cualquier modificación realizada.

Y una vez que se conservan las modificaciones, también restablece la bandera IsDirty a False.

Espero que esto ayude.

+0

Gracias por todas las respuestas chicos. Acepté esta respuesta ya que era la primera y tenía la mayoría de los votos a favor. –

+1

Esto suena mucho como CSLA. Si está usando .NET, recomendaría verificarlo. http://www.lhotka.net –

1

Si tiene un conjunto de objetos que se están editando, es probable que necesite algo más que un indicador booleano para isDirty(). Este problema no es diferente al recuento de referencias, es decir, incrementa un conteo sucio en edición y disminuye al deshacer. Si estás apoyando deshacer sospecho que vas a terminar con una lógica bastante peluda. Lo mantendría alejado de tus objetos de dominio.

1

Sí, esto funciona bien. En lugar de deshacer, utilizo el método IsDirty para indicar que algo PUEDE haber cambiado el registro y luego eso desencadena mi "lógica de cambio de registro". Desarrollé mi propio marco, donde cada campo de tabla es en realidad una propiedad de un objeto. Cada vez que se escribe un campo en los objetos, se establece el indicador "isDirty". En el método "SaveObject" del objeto (en realidad es una clase auxiliar pero podría estar fácilmente en el objeto, pero quería la capacidad de guardar objetos de diferentes maneras, como xml, base de datos, etc.), verifico el IsDirty y si es falso, entonces salteo el guardado. Esto simplifica la lógica ya que cada vez que tuve la posibilidad de cambiar el objeto, llamé a SaveObject y dejé que el framework lo manejara.

2

Si está utilizando .NET Framework, es posible que desee echar un vistazo a marco CSLA .NET Rockford Lhotka: http://www.lhotka.net/cslanet/Default.aspx

CSLA es un marco madura que incluye la gestión de estado del objeto (IsDirty), deshacer la funcionalidad, enlace de datos y mucho más, además es gratuito y de código abierto.

1

Según su dominio, puede usar la igualdad para comprobar las diferencias. Guarde el objeto original y haga una copia del objeto para editarlo. Cada vez que se realice una edición, modifique la UI de manera apropiada.

El beneficio de esta sugerencia es que no se pegue la funcionalidad específica interfaz gráfica de usuario (la bandera isDirty()) en sus objetos de dominio, pero tu caso es distinto

operación
1

Si admite deshacer a un nivel de granularidad mayor que 'Deshacer todo desde el último guardado', entonces sugeriría una pila de deshacer. Cuando se edita algo, se agrega (o se deshace el functor o delegado de la operación) a la pila. Cuando deshacer, simplemente abre la pila y deshace la operación reventada. Su indicador isDirty() es simplemente una verificación si la pila de deshacer contiene elementos, en lugar de almacenamiento adicional y lógica para actualizar.

+0

Gracias por la sugerencia. Me pregunto dónde viviría la pila de deshacer. ¿Es un objeto separado en un UndoManager o de algún tipo, donde la pila está vinculada al objeto de dominio que está editando? –

2

Hay un par de interfaces que puede implementar que ayudan con el seguimiento de cambios y deshacer: INotifyPropertyChanged e IEditableObject. Ambas interfaces permiten que el objeto juegue bien con databinding.

public class Person : INotifyPropertyChanged, IEditableObject 
{ 
    private bool isDirty; 

    public bool IsDirty 
    { 
     get { return isDirty; } 
    } 

    private string firstname = string.Empty; 

    public string Firstname 
    { 
     get { return firstname; } 
     set 
     { 
      if (firstname == value) return; 
      firstname = value; 
      NotifyPropertyChanged("Firstname"); 
     } 
    } 

    private string lastname = string.Empty; 

    public string Lastname 
    { 
     get { return lastname; } 
     set 
     { 
      if (lastname == value) return; 
      lastname = value; 
      NotifyPropertyChanged("Lastname"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void NotifyPropertyChanged(string propertyName) 
    { 
     isDirty = true; 

     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    private bool inTrans; 
    private Person copy; 

    public void BeginEdit() 
    { 
     if (!inTrans) 
     { 
      if (copy == null) 
       copy = new Person(); 

      copy.isDirty = isDirty; 
      copy.Firstname = Firstname; 
      copy.Lastname = Lastname; 


      inTrans = true; 
      isDirty = false; 
     } 
    } 

    public void CancelEdit() 
    { 
     if (inTrans) 
     { 
      isDirty = copy.isDirty; 
      Firstname = copy.Firstname; 
      Lastname = copy.Lastname; 

      inTrans = false; 
     } 
    } 

    public void EndEdit() 
    { 
     if (inTrans) 
     { 
      copy = null; 
      inTrans = false; 
     } 
    } 
}