angularjs - Angular Js+ TypeScript: Cómo crear una tabla dinámica
Soy nuevo en TypeScript y Angular. He implementado un módulo usando TypeScript y AngularJS, en el cual necesito crear una tabla dinámica que obtenga el tipo de presentación y, en consecuencia, lo agregue a mi vista, como lo he hecho anteriormente en C#. Mi código en C# lo he dado a continuación:
private void ShowCustomFields()
{
Customer.CustomerController control = new Customer.CustomerController();
DataTable fields = control.GetCustomFields();
TableRow row = new TableRow();
Int16 count = 0;
foreach (DataRow dr in fields.Rows)
{
count++;
string id = dr["Id"].ToString();
string name = dr["Name"].ToString();
string type = dr["Type"].ToString();
string val = "";
//Determine if the user can view/edit this custom field
bool canEdit = false;
if (Permissions.PermissionController.HasPermission(this.UserInfo.Username, "Custom Fields - Customer",
dr["Name"].ToString(),
Permissions.PermissionLevels.Edit))
{
canEdit = true;
}
TableCell cellId = new TableCell();
cellId.Visible = false;
cellId.EnableViewState = true;
cellId.Text = id;
TableCell cellName = new TableCell();
cellName.Text = name + ": ";
cellName.Width = 150;
cellName.EnableViewState = true;
TableCell cellControl = new TableCell();
cellControl.EnableViewState = true;
TextBox tb = new TextBox();
if (!canEdit)
{
tb.Enabled = false;
}
tb.TabIndex = (Int16)(1000 + count);
RangeValidator r = new RangeValidator();
switch (type)
{
case "Text":
tb.Text = val;
tb.ID = "CustomField" + id;
tb.EnableViewState = true;
tb.CssClass = "NormalTextBox";
cellControl.Controls.Add(tb);
break;
case "Integer":
tb.Text = val;
tb.ID = "CustomField" + id;
tb.EnableViewState = true;
tb.CssClass = "NormalTextBox";
cellControl.Controls.Add(tb);
r.ControlToValidate = tb.UniqueID;
r.Type = ValidationDataType.Integer;
r.MinimumValue = Int32.MinValue.ToString();
r.MaximumValue = Int32.MaxValue.ToString();
r.ErrorMessage = "Invalid Integer";
cellControl.Controls.Add(r);
break;
case "Decimal":
tb.Text = val;
tb.ID = "CustomField" + id;
tb.EnableViewState = true;
tb.CssClass = "NormalTextBox";
cellControl.Controls.Add(tb);
r.ControlToValidate = tb.UniqueID;
r.Type = ValidationDataType.Double;
r.MinimumValue = "-1000000000000";
r.MaximumValue = "1000000000000";
r.ErrorMessage = "Invalid Decimal";
cellControl.Controls.Add(r);
break;
case "Date":
tb.Text = val;
tb.ID = "CustomField" + id;
tb.EnableViewState = true;
tb.CssClass = "NormalTextBox";
cellControl.Controls.Add(tb);
r.ControlToValidate = tb.UniqueID;
r.Type = ValidationDataType.Date;
r.MinimumValue = "1/1/1900";
r.MaximumValue = "12/31/3000";
r.ErrorMessage = "Invalid Date";
cellControl.Controls.Add(r);
break;
case "TrueFalse":
CheckBox cb = new CheckBox();
if (val.ToUpper().Equals("TRUE"))
{
cb.Checked = true;
}
cb.EnableViewState = true;
cb.CssClass = "NormalTextBox";
cb.TabIndex = (Int16)(1000 + count);
cellControl.Controls.Add(cb);
break;
case "DropdownList":
DropDownList ddl = new DropDownList();
Vbos.Maintenance.MaintenanceController mcon = new Vbos.Maintenance.MaintenanceController();
ddl.DataSource = mcon.GetTypeItems("CF_" + name);
ddl.DataTextField = "Description";
ddl.DataValueField = "ShortDescription";
ddl.DataBind();
ListItem li = new ListItem();
li.Text = "--Select--";
li.Value = "-1";
li.Selected = true;
ddl.Items.Insert(0, li);
if (ddl.Items.FindByValue(val) != null)
{
ddl.SelectedIndex = -1;
ddl.Items.FindByValue(val).Selected = true;
}
cellControl.Controls.Add(ddl);
break;
}
row.Cells.Add(cellId);
row.Cells.Add(cellName);
row.Cells.Add(cellControl);
row.EnableViewState = true;
tableCustomFields.Rows.Add(row);
//if( count%2 == 0 )
//{
row = new TableRow();
//}
tableCustomFields.EnableViewState = true;
}
}
Como puedes ver, puedo obtener datos en función del tipo. Cómo puedo implementar lo mismo usando Angular Js y quiero saber cómo puedo enlazar estos valores con mi ng-model también.
Respuesta #1
Con Angular podrías usar un módulo como uiGrid, como sugiere @Dean Ward (¿cómo va todo Dean?). O podrías hacerlo tú mismo.
La esencia de tu código C# es imperativa y podría traducirse a TypeScript de alguna manera. Sin embargo, esto no sería recomendable. Gran parte de la construcción de tablas basada en datos reales se puede hacer de manera declarativa utilizando las directivas existentes de Angular.
El núcleo de tu código muestra la celda según su tipo. Esto podría implementarse como una directiva envolvente simple que se reemplazará a sí misma con una directiva para el tipo apropiado.
Para cada tipo de celda, puedes crear una directiva personalizada: celda-entera, celda-decimal, celda-desplegable, celda-booleana... Cada una manejaría cómo se muestra la celda y cómo se renderiza el control.
Entonces podrías usar ng-repeat para cada columna y fila, y dejar que la directiva contenedora se reemplace a sí misma con una directiva de tipo personalizado.
Otra ventaja de este enfoque es que tienes una mejor separación de responsabilidades, sigue el principio de abierto/cerrado y tus componentes solo harían una cosa.
Si la directiva del envoltorio utilizara una convención para mostrar las directivas de tipo, podrías agregar nuevos tipos en el futuro sin la necesidad de abrir ningún componente existente.
Esto es mucho trabajo para alguien nuevo en Angular. Yo seguiría la sugerencia de @Dean Ward. Hay muchas soluciones de cuadrícula editable para Angular. Si uiGrid no se ajusta a tus necesidades, mira otros componentes existentes.
ACTUALIZACIÓN Algunos ejemplos
Tu mejor opción sigue siendo usar un componente de cuadrícula existente, como uiGrid. Si quieres escribir esto tú mismo, lo cual no recomiendo, esta sería una forma de hacerlo.
function cellInteger(): ng.IDirective {
return {
scope: {data: '='},
controller: 'CellIntegerController',
controllerAs: 'vm',
bindToController,
templateUrl: 'path/to/integer.html'
}
}
gridMobule.directive('cellInteger', cellInteger);
export class CellIntegerController {
public data: CellDataType;
constructor() {}
save(value: number) {
this.data.value = number;
}
}
gridModule.controller('CellIntegerController', CellIntegerController);
En tu opinión, para esto tendrías algo como:
<input
type="number"
class="cell-integer"
ng-model="vm.data.value"
ng-blur="save(vm.data.value)"
</
