How can I make mat-tree from REST API (MongoDB and express) using Angular 8?

huangapple go评论70阅读模式
英文:

How can I make mat-tree from REST API (MongoDB and express) using Angular 8?

问题

我对Angular框架不太熟悉,但是我可以帮你翻译你提供的代码和描述。以下是翻译好的部分:

// 在后端服务器配置中编写的代码
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

let MainTree = new Schema({
   id: {
      type: String
   },
   name: {
      type: String
   },
   children: {
      type: Array
   }
}, {
      collection: 'TreeData'
})

module.exports = mongoose.model('MainTree', MainTree)

// tree.route.js 文件定义了路由和可以被服务 API 调用的函数
const express = require('express');
const app = express();
const treeRoute = express.Router();

let TreeData = require('../models/MainTree');

treeRoute.route('/').get((req, res) => {
    TreeData.find((error, data) => {
      if (error) {
        return next(error)
      } else {
        res.json(data)
      }
    })
})
module.exports = treeRoute;

// tree.service.ts 文件是服务 API
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})

export class TreeService {
  baseUri: string = 'http://localhost:4000/api';

  constructor(private http: HttpClient) { }
  getTreeData() {
    return this.http.get(`${this.baseUri}`);
  }
}

// demo-tree.component.ts 文件是通过 tree.service.ts 从后端获取数据的组件.ts 文件
import { Component, OnInit } from '@angular/core';
import { TreeService } from '../service/tree.service';

@Component({
  selector: 'app-demo-tree',
  templateUrl: './demo-tree.component.html',
  styleUrls: ['./demo-tree.component.css']
})
export class DemoTreeComponent implements OnInit {
  Tree: any = [];
  constructor(private Data: TreeService) { }
  getData() {
    this.Data.getTreeData().subscribe((data) => {
      this.Tree = data;
     })    
  }
  ngOnInit() {
  }
}

// demo-tree.component.html 文件是 HTML 文件,用于检索 Tree 数组,显示消息 'There is no item added yet!',这是正确的,因为我们还没有在后端数据库中添加任何项目或节点。
<p *ngIf="Tree.length <= 0" class="no-data text-center">There is no item added yet!</p>
// 其他显示 mat-tree 数据的部分省略

// 我想知道如何在我的后端服务器中创建树状结构并检索该数据。
// 我已经阅读了这个问题的答案,但不适合我的要求。
// 链接:https://stackoverflow.com/questions/58519241/is-there-a-way-to-generate-a-mat-tree-from-a-database
// 谢谢。

希望这有助于理解你的代码和问题。如果你需要进一步的帮助,请随时提出。

英文:

I am new to the Angular framework and want to generate a mat-tree from REST API which is made in MongoDB.
I have created a model in the backend for retrieving data from the backend database.
Below is a code which is written on the backend server configuration.

const mongoose = require(&#39;mongoose&#39;);
const Schema = mongoose.Schema;
let MainTree = new Schema({
id: {
type: String
},
name: {
type: String
},
children: {
type: Array
}
}, {   
collection: &#39;TreeData&#39;
})
module.exports = mongoose.model(&#39;MainTree&#39;, MainTree)

tree.routee.js this file defining route and functions which can be called by service api.

const express = require(&#39;express&#39;);
const app = express();
const treeRoute = express.Router();
let TreeData = require(&#39;../models/MainTree&#39;);
treeRoute.route(&#39;/&#39;).get((req, res) =&gt; {
TreeData.find((error, data) =&gt; {
if (error) {
return next(error)
} else {
res.json(data)
}
})
})
module.exports = treeRoute;

tree.service.ts this is service api

import { Injectable } from &#39;@angular/core&#39;;
import { HttpClient, HttpHeaders, HttpErrorResponse } from &#39;@angular/common/http&#39;;
@Injectable({
providedIn: &#39;root&#39;
})
export class TreeService {
baseUri:string = &#39;http://localhost:4000/api&#39;;
constructor(private http: HttpClient) { }
getTreeData(){
return this.http.get(`${this.baseUri}`);
}
}

demo-tree.component.ts this is component.ts file which is getting data from backend via tree.service.ts

import { Component, OnInit } from &#39;@angular/core&#39;;
import { TreeService } from &#39;../service/tree.service&#39;;
@Component({
selector: &#39;app-demo-tree&#39;,
templateUrl: &#39;./demo-tree.component.html&#39;,
styleUrls: [&#39;./demo-tree.component.css&#39;]
})
export class DemoTreeComponent implements OnInit {
Tree:any = [];
constructor(private Data: TreeService) { }
getData(){
this.Data.getTreeData().subscribe((data) =&gt; {
this.Tree = data;
})    
}
ngOnInit() {
}
}

demo-tree.component.html this is HTML file which is retrieving Tree Array, showing message 'There is no item added yet!' and this is right because we have not added any item or node in backend database.

&lt;p *ngIf=&quot;Tree.length &lt;= 0&quot; class=&quot;no-data text-center&quot;&gt;There is no item added yet!&lt;/p&gt;

else showing mat-tree data like that.

I want to know how I can make a tree-like structure in my backend server and retrieve that data.
https://stackoverflow.com/questions/58519241/is-there-a-way-to-generate-a-mat-tree-from-a-database I have read the answer to this question but didn't appropriate for my requirement.

Thanks.

答案1

得分: 1

/** File node data with nested structure. */
export interface FileNode {
  id: string;
  name: string;
  children?: FileNode[];
}

/** Flat node with expandable and level information */
export interface TreeNode {
  id: string;
  name: string;
  level: number;
  expandable: boolean;
}

/** The TreeControl controls the expand/collapse state of tree nodes. */
treeControl: FlatTreeControl<TreeNode>;

/** The TreeFlattener is used to generate the flat list of items from hierarchical data. */
treeFlattener: MatTreeFlattener<FileNode, TreeNode>;

/** The MatTreeFlatDataSource connects the control and flattener to provide data. */
dataSource: MatTreeFlatDataSource<FileNode, TreeNode>;

ngOnInit() {
  this.getData();
  this.treeFlattener = new MatTreeFlattener(
    this.transformer,
    this.getLevel,
    this.isExpandable,
    this.getChildren,
  );

  this.treeControl = new FlatTreeControl<TreeNode>(this.getLevel, this.isExpandable);
  this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
}

getData() {
  this.Data.getTreeData().subscribe((data) => {
    this.Tree = data;
    this.dataSource.data = data;
  })
}

/** Transform the data to something the tree can read. */
transformer(node: FileNode, level: number) {
  return {
    id: node.id,
    type: node.type,
    level: level,
    expandable: !!node.children
  };
}

/** Get the level of the node */
getLevel(node: TreeNode) {
  return node.level;
}

/** Return whether the node is expanded or not. */
isExpandable(node: TreeNode) {
  return node.expandable;
};

/** Get the children for the node. */
getChildren(node: FileNode) {
  return of(node.children);
}

/** Get whether the node has children or not. */
hasChild(index: number, node: TreeNode) {
  return node.expandable;
}
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
  <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle matTreeNodePadding>
    <button mat-icon-button disabled></button>
    {{node.name}}
  </mat-tree-node>

  <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
    <button mat-icon-button matTreeNodeToggle
            [attr.aria-label]="'toggle ' + node.name">
      <mat-icon>
        {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
      </mat-icon>
    </button>
    {{node.name}}
  </mat-tree-node>
</mat-tree>
英文:

Component.ts

/** File node data with nested structure. */
export interface FileNode {
id: string;
name: string;
children?: FileNode[];
}
/** Flat node with expandable and level information */
export interface TreeNode {
id: string;
name: string;
level: number;
expandable: boolean;
}
/** The TreeControl controls the expand/collapse state of tree nodes.  */
treeControl: FlatTreeControl&lt;TreeNode&gt;;
/** The TreeFlattener is used to generate the flat list of items from hierarchical data. */
treeFlattener: MatTreeFlattener&lt;FileNode, TreeNode&gt;;
/** The MatTreeFlatDataSource connects the control and flattener to provide data. */
dataSource: MatTreeFlatDataSource&lt;FileNode, TreeNode&gt;;
ngOnInit() {
this.getData();
this.treeFlattener = new MatTreeFlattener(
this.transformer,
this.getLevel,
this.isExpandable,
this.getChildren,
);
this.treeControl = new FlatTreeControl&lt;TreeNode&gt;(this.getLevel, this.isExpandable);
this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
}
getData(){
this.Data.getTreeData().subscribe((data) =&gt; {
this.Tree = data;
this.dataSource.data = data;
})    
}
/** Transform the data to something the tree can read. */
transformer(node: FileNode, level: number) {
return {
id: node.id,
type: node.type,
level: level,
expandable: !!node.children
};
}
/** Get the level of the node */
getLevel(node: TreeNode) {
return node.level;
}
/** Return whether the node is expanded or not. */
isExpandable(node: TreeNode) {
return node.expandable;
};
/** Get the children for the node. */
getChildren(node: FileNode) {
return of(node.children);
}
/** Get whether the node has children or not. */
hasChild(index: number, node: TreeNode){
return node.expandable;
}

Component.html

&lt;mat-tree [dataSource]=&quot;dataSource&quot; [treeControl]=&quot;treeControl&quot;&gt;
&lt;mat-tree-node *matTreeNodeDef=&quot;let node&quot; matTreeNodeToggle matTreeNodePadding&gt;
&lt;button mat-icon-button disabled&gt;&lt;/button&gt;
{{node.name}}
&lt;/mat-tree-node&gt;
&lt;mat-tree-node *matTreeNodeDef=&quot;let node;when: hasChild&quot; matTreeNodePadding&gt;
&lt;button mat-icon-button matTreeNodeToggle
[attr.aria-label]=&quot;&#39;toggle &#39; + node.name&quot;&gt;
&lt;mat-icon&gt;
{{treeControl.isExpanded(node) ? &#39;expand_more&#39; : &#39;chevron_right&#39;}}
&lt;/mat-icon&gt;
&lt;/button&gt;
{{node.name}}
&lt;/mat-tree-node&gt;
&lt;/mat-tree&gt;

huangapple
  • 本文由 发表于 2020年1月3日 21:58:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/59579844.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定