Añadir botón en columna del grid Telerik Kendo MVC

En esta fantástica suite de Telerik, podemos encontrar un grid completamente configurable y hoy voy  a apuntar cómo añadir un botón como columna, que nos puede servir para llamar al Controller para que ejecute su acción y luego añadiré un mensajito de confirmación en javascript. Vamos allá:

VIEW (no completa):

 @(Html.Kendo().Grid<RealCourseViewModel>()
.Name(“grid”)
          .Columns(columns =>
{
              columns.Bound(c => c.Code);
columns.Bound(c => c.Name);
              columns.Bound(c => c.Id).Title(“”).ClientTemplate(“<text><a href='” + @Url.Action(“Edit”) + “/#:data.Id#'</a>Ver</text>”).Width(70).Filterable(false);
//AQUÍ EL BOTÓN
              columns.Command(command => command.Custom(“Acción”).Click(“clickAction”)).Width(180);
})
y el javascript:
 function clickAction(e) {
e.preventDefault();

        var tr = $(e.target).closest(“tr”);

// get the data bound to the current table row
var dataItem = this.dataItem(tr);

        $.ajax({
type: “POST”,
url: ‘@Url.Action(“Metodo_Controller”)’,
content: “application/json; charset=utf-8”,
dataType: “json”,
data: { id: dataItem.Id },
success: function (d) {
if (d.Success === “true”) {
                    //borro la fila del botón… por hacer algo
var grid = $(“#grid”).data(“kendoGrid”);
grid.dataSource.remove(dataItem);
grid.dataSource.sync();
}
else {
alert(“ERROR.”);
}
},
error: function (xhr, textStatus, errorThrown) {
alert(“ERROR.”);
}
});

 

}

y el CONTROLLER:
 [HttpPost]
public JsonResult Metodo_Controller(int id)
{
           //aquí haremos las virguerías…
var result = new { Success = “true” };
return Json(result);
        }
Pues ya está, así de simple… me encanta Telerik… ¿se nota?
🙂

Proyectos ágiles: “mi Scrum”

Roles:

  • Dueño del Producto o Product Owner:
    • Conoce su negocio y sabe lo que necesita, por tanto, crea la lista de ítems de la pila del producto (PBIs), la ordena y la prioriza.
    • Debe asegurarse de que todos comprenden los PBIs.
    • Generará y mantendrá el plan de las entregas.
    • Puede delegar las tareas anteriores al equipo de desarrollo, pero hay que recordar que él seguirá siendo el responsable.
    • Podrá cambiar las prioridades según avanza el proyecto.
    • El PO será una única persona.
    • El cliente debe respetar sus decisiones.
  • Scrum Master:
    • Líder, auto-organizado y multi-funcional.
    • Garantiza que tanto el PO como el equipo trabajan en el día a día del proyecto como un todo.
    • Debe proteger, guiar y motivar al equipo de desarrollo.
    • Debe asegurarse de que no se interrumpa al equipo.
    • Debe preparar las reuniones y convocar a los participantes.
    • Debe realizar el seguimiento de las tareas que asigne al equipo.
  • Equipo de desarrollo:
    • Formado de no menos de 3 y hasta 9 personas.
    • Individuos generalistas con capacidades especiales.
    • Debe ser auto-organizado.
    • Todos son iguales, sin líderes, sin especialistas exclusivos, sin jerarquías.
    • Se encarga de descomponer los PBI en tareas menores, que se puedan realizar en 1 día.
    • Al finalizar el sprint entregarán el incremento del producto con las historias de usuario terminadas, probadas y comprobadas.
    • La responsabilidad corresponde al equipo como un todo.

Artefactos:

  • Pila del producto o Product Backlog: lista inicial de tareas a realizar. Deberá ser definida y priorizada por el dueño del producto.
  • Pila del Sprint o Sprint Backlog: formado por los PBIs que se realizan durante un sprint. A cada sprint se le asignarán los que se puedan desarrollar durante su duración (1 a 4 semanas). Los PBIs se descomponen en tareas que se puedan realizar durante un día. Por tanto, la Pila del Sprint es un elemento vivo que solo el equipo puede modificar durante el desarrollo del sprint, añadiendo o eliminando tareas según las necesidades. Si terminamos todos los PBIs antes de que finalice el sprint, simplemente añadiremos nuevos PBIs, y si vamos con retraso, los sacaremos.
  • Gráfica Burndown: al finalizar el sprint, todas sus tareas se marcan con “trabajo pendiente” igual a cero (si es que se ha terminado). La gráfica debe mostrar una caída, que podremos analizar para ver si se cumplen los objetivos.

Reuniones:

  • Planificación del sprint: el Scrum Master se reúne con el Dueño del Producto y decidirán las tareas a realizar en el sprint. El equipo de desarrollo es el que debe aprobar que estas tareas se pueden realizar en ese tiempo.
    • ¿qué se entregará al finalizar el sprint? ¿Qué PBIs se podrán entregar?
    • ¿cómo se hará el trabajo? El diseño completo se realizará durante el sprint, pero sí se definirá a alto nivel por parte del SM y el equipo.
  • Diaria: facilita la comunicación dentro del equipo y con el SM y da visibilidad a los problemas. No dura más de 15 minutos.
    • ¿qué hemos hecho desde ayer?
    • ¿qué problemas hemos tenido?
    • ¿qué vamos a hacer hoy?
    • ¿qué problemas vamos a tener que nos impidan cumplir el objetivo del sprint? El SM deberá resolverlos cuanto antes organizando las reuniones necesarias.
  • Revisión del sprint, Sprint Review, Demo: no debería superar 1 hora por semana trabajada. Al finalizar el sprint, con las funcionalidades “terminadas”, se le hace una demostración al PO. Si éste da su visto bueno, las tareas se marcan como realmente terminadas y la Gráfica Burndown, cae. Si las tareas no se terminan completamente, se actualiza el tiempo que falta para terminarse y las tareas se asignarán a otro sprint durante la Reunión de Planificación.
  • De retrospectiva: es el corazón de la mejora continua. Su duración es algo menor que la de Revisión. Tras la demo al cliente, el Scrum Master y el equipo analizan los problemas que hayan podido ocurrir y ven cómo mejorar para el siguiente sprint.

Estimación:

Partimos de la cruda realidad, realizar estimaciones ágiles certeras en proyectos ágiles:

  • No tiene sentido al principio del proyecto, ya que el nivel de incertidumbre es alto y la posibilidad de acertar es extremadamente baja.
  • Reducir la incertidumbre inicial, solo nos puede llevar a perder gran parte del tiempo analizando en lugar de avanzando.
  • Estimar es hacer una predicción y en el inicio del proyecto la incertidumbre es muy alta, por tanto, más que una predicción es una apuesta.
  • Hay que estimar porque es necesario para tomar decisiones, pero las probabilidades de equivocarnos van en función de la incertidumbre.

Hay muchas técnicas para estimar mejor, pero no debemos caer en la trampa de engañarnos para que las estimaciones cumplan el plazo del cliente. Los factores que nos ayudan a auto engañarnos para cumplir con plazos y el presupuesto del cliente son:

  • Pensar que como ya lo hemos hecho antes, ahora constará menos. ¿Pero estamos seguros de que no nos encontraremos con problemas nuevos?
  • La tarea a realizar parece sencilla. Seguro que el cliente conoce bien su negocio, pero nosotros en el inicio no.
  • En caso de no llegar a tiempo, siempre podemos echar mano de otros. Falso. Ley de Brooks.

En los proyectos las horas suelen aumentar rápidamente, y rara vez se cumplen los cálculos hechos en las primeras estimaciones. Por tanto, debemos evitar:

  • Realizar tareas que no se hayan solicitado, como mejoras que pensamos que el cliente no ha pedido, pero sí que necesita (“featuritis”). Además, debemos tener en cuenta que: “Cada funcionalidad tiene un coste de mantenimiento, por lo que tener menos funcionalidades nos permite trabajar en aquellas que realmente importan y nos aseguramos de que funcionen bien” (David Karp).
  • Abrumarnos por lo que falta, en lugar de ver cuánto hemos avanzado y ver si hay algún modo más sencillo de alcanzar el objetivo.
  • Las prisas. Nuestro trabajo perderá en calidad y finalmente los problemas sin resolver o a medio resolver aparecerán más tarde, cuando seguramente se necesitará más tiempo para resolverlo. “Las deudas técnicas se pagan más tarde con elevados intereses”.
  • Ampliar el equipo cuando el proyecto va retrasado. Ley de Brooks.

¿Cómo estimar?

Tras reunirnos con el PO y analizar los requerimientos, tendremos una lista más o menos detallada de las funcionalidades a desarrollar. A partir de ese momento llegaremos a tres niveles de estimación:

  1. La primera estimación a alto nivel usando tallas (S, M, L, XL, XXL).
  2. Para la segunda estimación de nivel medio, deberemos primero detallar a menor nivel estos PBIs en otros de menor nivel llamados Historias de Usuario. Para definir estas historias debemos:
    • Definir los roles.
    • Detallar las historias de usuario.
    • Estimar las historias utilizando una técnica comparativa llamada Estimación Relativa, como puede ser la sucesión Fibonacci (1, 2, 3, 5, 8, 13, 21, 40, 100).
  3. Durante el sprint el equipo de desarrollo hace la última estimación a bajo nivel, que se hará en horas ésta se realiza al descomponer de los PBIs en tareas más pequeñas. (Hay otras técnicas de estimación como el Método Delphi o el Planning Poker).

Buenas prácticas:

  • Reuniones diarias del equipo de trabajo de no más de 15 minutos:
    • ¿Qué vamos a hacer hoy?
    • ¿Con que problemas nos hemos enfrentado?
  • Las tareas necesitan de un tiempo para llevarse a cabo. Este tiempo debe ser el necesario, si damos menos tiempo, la tarea se realizará sin la calidad suficiente y los problemas surgirán más adelante.
  • Evitar interrumpir al equipo. Cuando se corta la concentración, aunque sea por unos segundos, retomar el trabajo donde se quedó, puede necesitar de otros 15 minutos.
  • Si es necesario modificar la rutina por que surgen incidencias, se procurará resumirlas de modo conciso y exponerlas al equipo todas juntas al finalizar la mañana o la tarde para retomarlas en la siguiente reunión diaria.

Fuentes:

http://geeks.ms/blogs/rcorral

http://www.kleer.la/

http://www.agilealliance.org/

No intellisense in Razor Views (ArgumentException in VS2015)

De repente, un día, vemos que el intellisense ha desaparecido de nuestras vistas en Razor, al abrirlas un mensaje nos indica que consultemos el fichero ActivityLog.xml en el que encontramos esto:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> System.ArgumentException: Item has already been added. Key in dictionary: ‘RazorSupportedRuntimeVersion’ Key being added: ‘RazorSupportedRuntimeVersion’ at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) at System.Collections.Hashtable.Add(Object key, Object value) at System.Collections.Specialized.HybridDictionary.Add(Object key, Object value) at Microsoft.VisualStudio.Utilities.PropertyCollection.AddProperty(Object key, Object property) at Microsoft.VisualStudio.Html.Package.Razor.RazorVersionDetector.Microsoft.Html.Editor.ContainedLanguage.Razor.Def.IRazorVersionDetector.GetVersion(ITextBuffer textBuffer) at Microsoft.Html.Editor.ContainedLanguage.Razor.RazorUtility.TryGetRazorVersion(ITextBuffer textBuffer, Version& razorVersion) at Microsoft.Html.Editor.ContainedLanguage.Razor.RazorErrorTagger..ctor(ITextBuffer textBuffer) — End of inner exception stack trace — at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark) at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) at System.Activator.CreateInstance(Type type, Object[] args) at Microsoft.Html.Editor.ContainedLanguage.Common.ContainedCodeErrorTaggerProvider`1.CreateTagger[T](ITextBuffer textBuffer) at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.GatherTaggers(ITextBuffer textBuffer)

Es un bug de Visual Studio 2015 en todas sus versiones y en el que ya está trabajando MS, pero de momento la solución es borrar la caché de VS:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe /ResetUserData

🙂

Binding Complex Types in MVC5

A la hora de editar tipos complejos de un ViewModel, olvídate de usar el “foreach” tal que:

public ViewModel()
{
Plantillas = new List<Informe>();
}

VIEW:

@foreach (var plantilla in @Model.Plantillas)
{

@Html.HiddenFor(x => plantilla.Id)

@(Html.EditorFor(x => plantilla.Orden))

}

De este modo al controlador no le llega nada, la solución sería usar un “for” :-):

@for(var i=0;i<Model.Plantillas.Count;i++)
{
@Html.HiddenFor(x => Model.Plantillas[i].Id)
@(Html.EditorFor(x => Model.Plantillas[i].Orden))

}

Pero en MVC4 ni por esas: http://guysherman.com/2013/04/12/asp-net-mvc4-binding-to-a-list-of-complex-types/

Este artículo actualiza a https://pdcuevas.wordpress.com/2015/02/20/editing-a-variable-length-list-with-aspnet-mvc/

Usar HTML 5 Storage para comunicar ventanas

El almacenamiento en local proporcionado por HTML 5, denominado Local Storage, puede también servirnos como modo de intercambio de información entre aplicaciones.

El sistema sería muy simple:

1- en la página source podríamos tener algo tan simple como:

< button type=”submit” onclick=”localStorage[‘refresh’]=0″ >botón</button>

2- y en la página target:

function reportStorage(evt) {

if (evt.key == ‘refresh’) { $(“#grid1”).igGrid(“dataBind”); } }

$(document).ready(function () { window.addEventListener(‘storage’, reportStorage, false); });

3- ampliar info aquí