Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

314
Visualizações
Cómo crear una lista desplegable y enlazar con datos provenientes del servidor

Soy muy nuevo en Angular. Tengo algo de trabajo en Angular.

Necesito vincular la lista desplegable anidada para los datos Json que provienen del servidor llamando a Rest Api.

Los datos tienen un atributo Nivel. Especifica el nivel en la jerarquía del grupo. El padre tendrá Child=1 , Grandchild=2 y así sucesivamente. Child and Grandchild tiene un campo de grupo, que muestra dentro de qué menú principal estará el menú secundario.

Lo intenté desarrollar, pero encontré todos los ejemplos de bootstrap con datos estáticos en un archivo html y un archivo CSS separado que me resultó complicado.

Quiero hacerlo dinámicamente usando TypeScript . ¿Cómo puedo empezar a trabajar en él.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Esta es una muestra codificada que necesita según los datos de nivel anidados de sus datos json. Ahora puede realizar un bucle forzado de los datos json formateados en el DOM utilizando datos del modelo . Espero que esto te ayude a crear un menú desplegable de varios niveles.

 groupBy(xs, key) { return xs.reduce(function (rv, x) { (rv[x[key]] = rv[x[key]] || []).push(x); return rv; }, {}); } var model; getData() { var sampleData = { "ArrayOfLocationGroup": { "LocationGroup": [ ... ...//Server response data ], "_xmlns:xsd": "http://www.w3.org/2001/XMLSchema" } } var list = this.sampleData["ArrayOfLocationGroup"]["LocationGroup"]; var formattedList = []; list.forEach(element => { var obj = { //Make sure your server response data to like this structure "Id": element.Id, "Name": element.Name, "GroupId": element.GroupId.__text, "ParentLocationGroup": element.ParentLocationGroup.__text, "LgLevel": element.LgLevel.__text, "Child" : [] } formattedList.push(obj); }); var groupDataList = this.groupBy(formattedList, "LgLevel"); var parents = groupDataList[0]; var child = groupDataList[1]; var childOfChild = groupDataList[2]; child.forEach(c => { c.Child = childOfChild.filter(x => x.ParentLocationGroup == c.Id); }) parents.forEach(p => { p.Child = child.filter(x => x.ParentLocationGroup == p.Id); }) this.model = parents; }

archivo html

 <ul class="nav site-nav"> <li class=flyout> <a href=#>Dropdown</a> <!-- Flyout --> <ul class="flyout-content nav stacked"> <li *ngFor="let parent of model" [class.flyout-alt]="parent.Child.length > 0"><a href=#>{{parent.Name}}</a> <ul *ngIf="parent.Child.length > 0" class="flyout-content nav stacked"> <li *ngFor="let c of parent.Child" [class.flyout-alt]="c.Child.length > 0"><a href=#>{{c.Name}}</a> <ul *ngIf="c.Child.length > 0" class="flyout-content nav stacked"> <li *ngFor="let cc of c.Child" [class.flyout-alt]="cc.Child.length > 0"><a href=#>{{cc.Name}}</a></li> </ul> </li> </ul> </li> </ul> </li> </ul>

Según los datos de respuesta de su servidor, organice los datos del modelo. El formato json de respuesta cambió ( __texto a #texto )

 var obj = { "Id": element.Id, "Name": element.Name && element.Name.#text ? element.Name.#text : element.Name, "GroupId": element.GroupId && element.GroupId.#text ? element.GroupId.#text : element.GroupId, "ParentLocationGroup": element.ParentLocationGroup && element.ParentLocationGroup.#text ? element.ParentLocationGroup.#text : element.ParentLocationGroup, "LgLevel": element.LgLevel && element.LgLevel.#text ? element.LgLevel.#text : element.LgLevel, "Child" : [] }
over 4 years ago · Santiago Trujillo Relatório

0

Parece que ya tiene otra respuesta que cumple con sus requisitos. Pero esta solución me tomó algún tiempo para llegar a. Así que decidí publicarlo de todos modos.

El siguiente fragmento de código se usa para construir la estructura de árbol de los datos jerárquicos padre-hijo:

 processData(data) { let locationData = data.ArrayOfLocationGroup.LocationGroup; let level0 = []; let tempMap = {}; for (let i = 0; i < locationData.length; i++) { let currItem = this.getDataObject(locationData[i]); if (tempMap[currItem.id] == undefined) { tempMap[currItem.id] = currItem; if (tempMap[currItem.parentLocationGroup] == undefined) { tempMap[currItem.parentLocationGroup] = { children: [] }; } tempMap[currItem.parentLocationGroup].children.push(currItem); } else { if (tempMap[currItem.id]) { currItem.children = tempMap[currItem.id].children; } tempMap[currItem.id] = currItem; if (tempMap[currItem.parentLocationGroup] == undefined) { tempMap[currItem.parentLocationGroup] = { children: [] }; } tempMap[currItem.parentLocationGroup].children.push(currItem); } if (currItem.lgLevel == "0") { if (level0.indexOf(currItem) == -1) { level0.push(currItem); } } } this.levelData = level0; }

Los datos agregados se pasan como entrada a un componente dropdown que los representa como un menú desplegable de varios niveles.

Esta solución supuestamente funcionará para cualquier nivel de niños. El componente dropdown se puede modificar para cambiar la forma en que se representan los datos según sus requisitos.

Tomé el html y css para el menú desplegable multinivel desde aquí:
https://phppot.com/css/multilevel-dropdown-menu-with-pure-css/
El código para cerrar el menú desplegable cuando se hace clic fuera de esta respuesta:
https://stackoverflow.com/a/59234391/9262488

Espero que encuentres esto útil.

over 4 years ago · Santiago Trujillo Relatório

0

¿Por qué no crear un componente de árbol y vincular entradas recursivamente?

La solución propuesta es

  • agnóstico en profundidad: funcionará para cualquier cantidad de niveles en su árbol de datos (incluso si cambia ad-hoc)
  • bastante eficiente: agrega sus datos en O(n) .

Primero diseñe el modelo de datos: tiene que ser una estructura de nodo de árbol:

 export interface GroupId { /* appropriate members... */ } export interface ParentLocationGroup { /* other members... */ __text: string; } export interface LgLevel { /* other members... */ __text: string; } export interface DataModel { Id: string, Name: string, GroupId: GroupId, ParentLocationGroup: ParentLocationGroup, LgLevel: LgLevel, children: DataModel[] }

Luego agregue sus datos en el componente de nivel superior (o incluso mejor, en su servicio de datos; debería poder abstraer eso con bastante facilidad):

 // dropdown.component.ts @Component({ selector: 'app-dropdown', template: ` <ul class="nav site-nav"> <li class=flyout> <a href=#>Dropdown</a> <app-dynamic-flyout [data]="data"></app-dynamic-flyout> </li> </ul> ` }) export class DropdownComponent { data: DataModel[]; constructor(dataService: YourDataService){ let data; dataService.getYourData() .pipe(map(d => d.ArrayOfLocationGroup.LocationGroup))) // Make sure every item has the `children` array property initialized // since it does not come with your data .subscribe(d => data = d.map(i => ({...i, children: []}))); // Create a lookup map for building the data tree let idMap = data.reduce((acc, curr) => ({...acc, [curr.Id]: curr}), {}); this.data = data.reduce( (acc, curr) => curr.LgLevel.__text == 0 || !curr.ParentLocationGroup // Either the level is 0 or there is no parent group // (the logic is unclear here - even some of your lvl 0 nodes have a `ParentGroup`) // -> we assume this is a top-level node and put it to the accumulator ? [...acc, curr] // Otherwise push this node to an appropriate `children` array // and return the current accumulator : idMap[curr.ParentLocationGroup.__text].children.push(curr) && acc, [] ); } }

Y cree el componente flotante dinámico recurrente:

 // dynamic-flyout.component.ts @Component({ selector: 'app-dynamic-flyout', template: ` <ul *ngIf="!!data.length" class="flyout-content nav stacked"> <li *ngFor="let item of data" [class.flyout-alt]="!!item.children.length"> <a href=#>{{item.Name}}</a> <app-dynamic-flyout [data]="item.children"></app-dynamic-flyout> </li> </ul> ` }) export class DynamicFlyoutComponent { @Input() data: DataModel[]; }

La solución no está probada, pero lo orientará en la dirección correcta...

Espero que esto ayude un poco :-)

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda