Постройте древовидный вид с флажком, используя материал и угол

#javascript #angular #angular-material

Вопрос:

У меня есть этот код :

 const TREE_DATA_JSON = {
idManager: 1,
label: 'Manager',
descendants: [
    {
        idManager: 2,
        label: 'Des 1',
        areaManagers: [
            {
                idManager: 3,
                label: 'Manager 1'
            },
            {
                idManager: 4,
                label: 'Manager 2'
            },
        ]
    }
]
 

};

 @Injectable()
export class ChecklistDatabase {
dataChange = new BehaviorSubject<TodoItemNode[]>([]);

get data(): TodoItemNode[] { return this.dataChange.value; }

constructor() {
    this.initialize();
}

initialize() {
    // Build the tree nodes from Json object. The result is a list of `TodoItemNode` with nested
    //     file node as children.
    const data = this.buildFileTree(TREE_DATA_JSON, 0);

    // Notify the change.
    this.dataChange.next(data);
}

/**
 * Build the file structure tree. The `value` is the Json object, or a sub-tree of a Json object.
 * The return value is the list of `TodoItemNode`.
 */
buildFileTree(obj: object, level: number): TodoItemNode[] {
    return Object.keys(obj).reduce<TodoItemNode[]>((accumulator, key) => {
        const value = obj[key];
        const node = new TodoItemNode();
        node.item = key;

        if (value != null) {
            if (typeof value === 'object') {
                node.children = this.buildFileTree(value, level   1);
            } else {
                node.item = value;
            }
        }

        return accumulator.concat(node);
    }, []);
}
 

}
Но у меня такой древовидный вид :

введите описание изображения здесь

У вас есть идея, как это изменить buildFileTree ? Дерево, которое я получаю от : https://stackblitz.com/angular/gabkadkvybq?file=app/tree-checklist-example.ts.

Заранее благодарю за ваше сообщение и прошу прощения за мой английский

Я хочу показать что-то вроде этого :

  • Менеджер
    • Des 1
      • Менеджер 1
      • Менеджер 2

Мой стакблитц : https://stackblitz.com/edit/angular-ivy-xdflat

Комментарии:

1. Привет, не могли бы вы, пожалуйста, сообщить нам, каков ваш ожидаемый результат. Поскольку пример Stackbliz, которым вы поделились, работает так, как ожидалось, показано на изображении, которым вы поделились.

2. Похоже, вы связали пример с запасом, предоставленный командой Angular Material, без каких-либо изменений. Пожалуйста, сначала попытайтесь выполнить это требование самостоятельно. Затем вы можете задать вопрос, когда столкнетесь с препятствием.

3. Привет @KIsdskldsd, я думаю, вместо использования FlatTree вы должны использовать NestedTree , пожалуйста, посмотрите на этот пример

4. @HimanshuSaxena мой код : stackblitz.com/edit/angular-ivy-xdflat

5. @MichaelD Я добавил свой stackblitz: stackblitz.com/edit/angular-ivy-xdflat

Ответ №1:

Это решение предполагает, что при выборе родителя вы автоматически хотите выбрать также каждого из его потомков. если вы хотите изменить это поведение, чтобы просто показывать потомкам, как только родитель будет проверен, но на самом деле не автоматически проверять потомков, дайте мне знать, и я смогу внести это изменение. Это довольно небольшое изменение.

Я также добавил в этот код прослушиватель событий, который автоматически снимает все флажки, когда соответствующий предок, необходимый для его видимости, снят. Запустите приведенный выше фрагмент, чтобы увидеть это в действии.

 const form = document.querySelector('form');
const TREE_DATA_JSON = [{
  idManager: 1,
  label: 'Manager',
  descendants: [{
    idManager: 2,
    label: 'Des 1',
    areaManagers: [{
        idManager: 3,
        label: 'Manager 1'
      }, {
        idManager: 4,
        label: 'Manager 2'
      },
    ]
  }]
}];

function buildTree(form, arr) {
  function fetchUniqueArr(obj) { return obj[Object.keys(obj).filter(key => !['idManager', 'label'].includes(key))]; }
  function buildTreeHTML(arr, nested = false) {
    return arr.map((field,i) => `${i?'<br>':''}<input id="field-${field.idManager}" type="checkbox"><label for="field-${field.idManager}">${field.label}</label>`   (Object.keys(field).length === 3 ? `<br><div class="nested-fields">${buildTreeHTML(fetchUniqueArr(field), true)}</div>` : '')).join('');
  }
  form.insertAdjacentHTML('beforeend', buildTreeHTML(arr));
}

document.addEventListener('change', e => e.target?.matches('form input[type="checkbox"]') amp;amp; e.target.nextElementSibling?.nextElementSibling?.nextElementSibling?.matches('.nested-fields') amp;amp; e.target.nextElementSibling.nextElementSibling.nextElementSibling.querySelectorAll('input[type="checkbox"]').forEach(field => field.checked = e.target.checked));

buildTree(form, TREE_DATA_JSON); 
 body {
  font-family: sans-serif;
  font-size: 16px;
  font-weight: 500;
}
form, .nested-fields {
  display: block;
}
.nested-fields {
  padding-left: 20px;
}
input:not(:checked)   label   br   .nested-fields {
  display: none;
} 
 <form></form> 

Если вы хотите поддерживать «неопределенные» значения флажков, когда родитель «наполовину проверен», когда проверяются только некоторые из его дочерних элементов, эта функциональность изначально не поддерживается в HTML/CSS/JS, но есть несколько библиотек, которые помогут вам достичь этого. Для дальнейшего чтения и примеров в списках неопределенных флажков ознакомьтесь с этой статьей Криса Койера о CSS-хитростях, Неопределенные флажки

Комментарии:

1. Не так, как ожидалось. Я должен использовать материал treeview. Вот мой код : stackblitz.com/edit/angular-ivy-xdflat

2. Не беспокойтесь, просто ванильное решение^ для всех, кто заинтересован в том, чтобы сделать это самостоятельно без API. Немного поработав, мы могли бы заставить это работать, даже в Ванили, с неопределенными значениями. Я также замечаю некоторые проблемы с этим материалом treevioew при дальнейшей работе с ним: i.imgur.com/Mth97cF.png