Проверьте рекурсивную структуру JSON на соответствие числовых значений в наборе в Typescript Angular - PullRequest
0 голосов
/ 08 мая 2019

У меня есть пользовательский интерфейс, где изначально пользователь должен установить некоторые флажки. Флажки имеют последовательные идентификаторы. Структура JSON для него следующая:

{
  "categories": [{
    "name": "Product",
    "labels": [{
      "id": 1,
      "name": "I work on an asset (capital good).",
      "checked": false
    }, {
      "id": 2,
      "name": "I work on a consumer product.",
      "checked": false
    }, {
      "id": 3,
      "name": "I am not sure what type of product I work on.",
      "checked": false
    }
    ]
  }, {
    "name": "Goal",
    "labels": [{
      "id": 4,
      "name": "I want to improve the product's reliability.",
      "checked": false
    }, {
      "id": 5,
      "name": "I need information to identify root causes.",
      "checked": false
    }, {
      "id": 6,
      "name": "I need information about the product's environment.",
      "checked": false
    }, {
      "id": 7,
      "name": "I need information about customer requirements.",
      "checked": false
    }, {
      "id": 8,
      "name": "I need quantified information.",
      "checked": false
    }, {
      "id": 9,
      "name": "I am not sure what I need.",
      "checked": false
    }
    ]
  }
]
}

Я отображаю его в угловом формате, используя следующий код:

component.html

<div class="row mt-lg-auto" *ngFor="let filter of filters['categories']">
    <div class="col-lg-12">
      <h4>
        {{filter['name']}}
      </h4>
      <div *ngFor="let label of filter['labels']">
          <div class="form-check">
            <input class="form-check-input"
                   type="checkbox"
                   value="{{label['id']}}"
                   id="{{label['id']}}"
                   [(ngModel)]="label['checked']"
                   (change)="changeCheck(label['id'], $event)"
            >
              <label class="form-check-label" for="{{label['id']}}">
                {{label['name']}}
              </label>
          </div>
      </div>
    </div>
  </div>

component.ts Я напрямую импортирую файл JSON из папки src/assets/ и сохраняю id в Set, чтобы избежать дублирования значений, когда пользователь выбирает флажок.

import { Component, OnInit } from '@angular/core';
import * as FilterFunc from 'src/assets/FilterFunction.json';

const Filters: any = FilterFunc;

@Component({
  selector: 'explore-step1',
  templateUrl: './explore-step1.component.html',
  styleUrls: ['./explore-step1.component.css']
})
export class ExploreStep1Component implements OnInit {
  filters = Filters.default;
  selections = new Set();

  constructor() {
  }
  ngOnInit(): void {
  }
  changeCheck(id: number, event: any) {
    (event.target.checked) ?
      this.selections.add(id):
      this.selections.delete(id);
    console.log(this.selections);
  }
}

Я использую ngx-treeview для рендеринга в виде дерева для фиксированного файла JSON, который имеет следующую структуру: GitHub Суть полного рекурсивного JSON

Здесь у детей в самой глубине есть следующая пара ключ-значение:

"value": {
     "label_ids": [relevant ids from the first json],
     "description": "some text to render"
}

иначе "значение" равно нулю.

Я хочу сравнить Set значения с вышеупомянутым рекурсивным JSON label_ids, и если одно или несколько значений в label_ids совпадают с Set, то измените значение checked на true

Как можно это сделать в Typescript / Angular?

1 Ответ

0 голосов
/ 09 мая 2019

Я решил это, создав функцию разбора рекурсии, которая принимает структуру JSON.

  1. В ngOnInit() я вызываю службу и передаю ее функции parseTree
  2. Я рекурсивно разбираю его и сравниваю значения с Set
  3. Я добавляю дополнительную информацию, такую ​​как текст класса Font-Awesome, в структуру value, чтобы сделать его
  4. передать обновленныйJSON для соответствующей items переменной

component.ts :

parseTree(factors: TreeviewItem[]) {
factors.forEach(factor => {
  // console.log(factor);
  if (!isNil(factor.value)) {
    let labels: number[] = factor.value['label_ids'];
    labels.forEach(label => {
      if(this.selected.findIndex(l => l == label) > -1) {
        factor.value['highlighted'] = true;
        factor.value['class'] = 'fas fa-flag';
      }
    });
  }
  if (!isNil(factor.children)) {
    this.parseTree(factor.children);
  }

});
this.items = factors;

}

здесь selections равно Set и в пределах ngOnInit()Я установил для него фиксированное значение:

ngOnInit() {
    this.selections.add(15);
    this.items = this.parseTree(this.service.getDataQualityFactors());
  }

На основе ngx-treeview пример Я использую itemTemplate в коде и добавляю Font-Awesome шрифты рядом с выделенными элементами следующим образом:

component.html

 <label class="form-check-label" *ngIf="item.value !== null && item.value['highlighted']">
        <i class="{{item.value['class']}}" aria-hidden="true" title="Highlighted" [ngClass]="{'marked': item.checked}"></i>
      </label>

и использование классов CSS для управления изменением цвета шрифта:

.fa-flag {
  color: red;
}
.fa-flag.marked {
  color: green;
}

Пример кода StackBlitz

...