Búsqueda de sitios web

typescript - Angular 2 ¿Cómo creo una estructura anidada?


Tengo un conjunto de expresiones y un ConjuntoDeCondiciones; cuando seleccionas ese, se creará una nueva línea de Expresión, esta está anidada. Creé esto como objeto objeto:

export class Expression {
    selector: string;
    constraint: string;
    value: string;
    children: Expression[];
}

Así que cuando se selecciona este ConditionSet quiero «mover» o duplicar esto a Expression.children. Ahora, si hago console.log de this.expressions agregando uno, se ve de la siguiente manera:

Pero como puedes ver, el cuadro de selección del medio está anidado y la arrivalDate tiene que estar anidada en el conditionSet.children así:

Expression { 
selector: "conditionSet",
value:"" 
children: 
          selector:"ArrivalDate", 
          value:"" 
 }

Y el addButton anidado también tiene que empujarlo a .children para crear el contenido anidado.

Estaba pensando de esta manera, pero esto no funciona :(:

if(this.expression.selector === 'conditionSet'){
            this.prototypes = this.prototypes.children;
            console.log(this.prototypes);
        }

¿Alguien puede ayudarme con esto? Realmente me estoy desesperando con este problema.

Aquí hay un PLUNKER

Respuesta #1

De hecho, no tienes el método addExpression definido en tu clase ExpressionComponent, solo en la clase ExpressionBuilderComponent. Por lo tanto, solo puedes agregar expresiones para el primer nivel...

Además, creo que no manejas correctamente el aspecto recursivo de tus datos.

Para el componente ExpressionBuilderComponent, necesitas proporcionar el arreglo expresion.children para el parámetro expressions del componente expression:

<expression *ngFor="#expression of expressions" [prototypes]="prototypes" [expression]="expression" [expressions]="expression.children"></expression>
<button class="btn btn-primary" (click)="addExpression()">Add Expression</button>

Lo mismo debe hacerse para el ExpressionComponent en sí:

<div class="col-xs-3">
  <select class="form-control" [(ngModel)]="selectedPrototypeSelector" (ngModelChange)="onPrototypeChange()">
    <option *ngFor="#p of prototypes" [value]="p.selector">
      {{ p.selectorName }}
    </option>
  </select>
</div>

<div *ngIf="prototype?.valueType === 'Set'">
  <div [ngClass]="{'nested-expression': prototype?.valueType === 'Set'}">
    <expression *ngFor="#expression of expressions" [prototypes]="prototypes" [expression]="expression" [expressions]="expression.children"></expression>
    <button class="btn btn-primary" (click)="addExpression()">Add Expression</button>
   </div>
 </div>

Mira este plunkr: https://plnkr.co/edit/zGcoZD?p=preview.

Editar

Con respecto a la eliminación, necesitas manejar un evento personalizado (@Ouput) para hacer eso, ya que necesitas eliminar el elemento de los hijos del padre:

<div class="col-xs-1">
  <button class="btn btn-danger pull-right" (click)="deleteExpression()">Delete</button>
</div>

<div *ngIf="prototype?.valueType === 'Set'">
  <div [ngClass]="{'nested-expression': prototype?.valueType === 'Set'}">
    <expression *ngFor="#expression of expressions"
            [prototypes]="prototypes"
            [expression]="expression"
            [expressions]="expression.children"
            (expressionDeleted)="onExpressionDeleted(expression)">
    </expression>
    <button class="btn btn-primary" (click)="addExpression()">Add Expression</button>
  </div>
  <div>{{expression | json}}</div>
</div>

y en el componente:

export class ExpressionComponent implements OnInit {
  (...)
  @Output() expressionDeleted: EventEmitter = new EventEmitter;

  (...)

  deleteExpression() {
    this.expressionDeleted.emit();
  }

  onExpressionDeleted(expression) {
    var index = this.expressions.indexOf(this.expression);
    this.expressions.splice(index, 1);
    console.log(index);
  }
}

Vea este plunkr para eliminar: https://plnkr.co/edit/rQCILc?p=preview.

Artículos relacionados