我想从带有适当子节点的JSON中仅提取标题和文本字段。
tree.component.html
<mat-tree [dataSource] = "dataSource" [treeControl] = "treeControl">
<mat-tree-node *matTreeNodeDef = "let node;" matTreeNodeToggle matTreeNodePadding>
<button mat-icon-button disabled ></button>
<span (click)="sendMessage(node)">{{node.name}} : {{node.id}}</span>
</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 class = "mat-icon-rtl-mirror">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
<span (click)="sendMessage(node)" >{{node.name}}</span>
</mat-tree-node>
tree.component.ts
import { Component, OnInit, Injectable, Output, EventEmitter } from '@angular/core';
import {FlatTreeControl} from '@angular/cdk/tree';
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
import {BehaviorSubject, Observable, of as observableOf} from 'rxjs';
import OfferData from 'src/assets/offerdata.json';
export class OfferTree {
children: OfferTree[];
name: string;
id: any;
}
export class OfferTreeFlatNode {
constructor(
public expandable: boolean,
public name: string,
public level: number,
public id: any) {}
}
const TREE_DATA = JSON.stringify({
sections: [
{
text: 'rhoncus elit molestie viverra ad consectetur sapien ipsum nunc arcu',
items: [
{
text: 'litora gravida efficitur purus erat molestie dui fames rhoncus convallis habitasse',
title: 'Position 1',
optional: false,
components: [
{
text: 'finibus habitasse libero rutrum sapien ligula eleifend eu et metus rhoncus justo vulputate iaculis pharetra eget aliquet parturient placerat consequat',
price: 184,
title: 'Komponente 1',
optional: false,
listPrice: 188,
modelClass: 'Project\\Offer\\Model\\Component',
priceAsText: '',
quantityMax: 20,
quantityMin: 10,
modelVersion: 1,
monthlyPrice: 0,
pricelistKey: null,
viewDiscount: true,
redxTemplateKey: 9,
systemComponent: true,
discountAbsolute: 0,
discountRelative: 0.2,
monthlyListPrice: 0,
monthlyPriceAsText: '',
termsAndConditions: '',
discountDescription: 'Komponentennachlass',
thirdPartyComponent: false,
offerComponentKeyTemplate: null,
addMonthlyPriceFromSystemComponents: false
},
{
text: 'nunc a nulla porttitor porta sit elementum congue sapien eros lacinia ornare eleifend mus pellentesque',
price: 144,
title: 'Komponente 2',
optional: true,
listPrice: 144,
modelClass: 'Project\\Offer\\Model\\Component',
priceAsText: '',
quantityMax: 8,
quantityMin: 8,
modelVersion: 1,
monthlyPrice: 0,
pricelistKey: null,
viewDiscount: false,
redxTemplateKey: 9,
systemComponent: true,
discountAbsolute: 0,
discountRelative: 0,
monthlyListPrice: 0,
monthlyPriceAsText: '',
termsAndConditions: '',
discountDescription: '',
thirdPartyComponent: false,
offerComponentKeyTemplate: null,
addMonthlyPriceFromSystemComponents: false
},
{
text: 'lacinia bibendum dictum fermentum platea vestibulum cubilia nascetur parturient ornare adipiscing ad diam conubia sapien',
price: 182,
title: 'Komponente 3',
optional: false,
listPrice: 182,
modelClass: 'Project\\Offer\\Model\\Component',
priceAsText: '',
quantityMax: 8,
quantityMin: 8,
modelVersion: 1,
monthlyPrice: 0,
pricelistKey: null,
viewDiscount: false,
redxTemplateKey: 9,
systemComponent: true,
discountAbsolute: 0,
discountRelative: 0,
monthlyListPrice: 0,
monthlyPriceAsText: '',
termsAndConditions: '',
discountDescription: '',
thirdPartyComponent: false,
offerComponentKeyTemplate: null,
addMonthlyPriceFromSystemComponents: false
}
],
modelClass: 'Project\\Offer\\Model\\Item',
modelVersion: 1,
viewDiscount: true,
printPricetable: true,
redxTemplateKey: 8,
discountAbsolute: 200,
discountRelative: 0,
termsAndConditions: null,
discountDescription: '',
offerItemKeyTemplate: null,
printGlobalPricetable: true,
printMonthlyPricetable: false,
printTermsAndConditions: false,
printGlobalMonthlyPricetable: false
},
{
text: 'imperdiet netus lorem rutrum felis commodo tincidunt tempus pretium fames pharetra phasellus duis rhoncus',
title: 'Position 2',
optional: false,
components: [
{
text: 'eu eget facilisis congue at tempor semper enim sed pretium nulla laoreet a malesuada morbi libero',
price: 181,
title: 'Komponente 1',
optional: true,
listPrice: 181,
modelClass: 'Project\\Offer\\Model\\Component',
priceAsText: '',
quantityMax: 7,
quantityMin: 6,
modelVersion: 1,
monthlyPrice: 0,
pricelistKey: null,
viewDiscount: false,
redxTemplateKey: 9,
systemComponent: false,
discountAbsolute: 0,
discountRelative: 0,
monthlyListPrice: 0,
monthlyPriceAsText: '',
termsAndConditions: '',
discountDescription: '',
thirdPartyComponent: false,
offerComponentKeyTemplate: null,
addMonthlyPriceFromSystemComponents: false
},
{
text: 'nascetur lorem dictumst sodales faucibus ipsum lectus suspendisse convallis sed quis suscipit consequat finibus ultrices',
price: 112,
title: 'Komponente 2',
optional: true,
listPrice: 112,
modelClass: 'Project\\Offer\\Model\\Component',
priceAsText: '',
quantityMax: 8,
quantityMin: 7,
modelVersion: 1,
monthlyPrice: 0,
pricelistKey: null,
viewDiscount: false,
redxTemplateKey: 9,
systemComponent: false,
discountAbsolute: 0,
discountRelative: 0,
monthlyListPrice: 0,
monthlyPriceAsText: '',
termsAndConditions: '',
discountDescription: '',
thirdPartyComponent: false,
offerComponentKeyTemplate: null,
addMonthlyPriceFromSystemComponents: false
},
{
text: 'nibh porta tincidunt placerat ligula ultricies pharetra felis ad lacinia varius',
price: 109,
title: 'Komponente 3',
optional: false,
listPrice: 109,
modelClass: 'Project\\Offer\\Model\\Component',
priceAsText: '',
quantityMax: 10,
quantityMin: 9,
modelVersion: 1,
monthlyPrice: 0,
pricelistKey: null,
viewDiscount: false,
redxTemplateKey: 9,
systemComponent: false,
discountAbsolute: 0,
discountRelative: 0,
monthlyListPrice: 0,
monthlyPriceAsText: '',
termsAndConditions: '',
discountDescription: '',
thirdPartyComponent: false,
offerComponentKeyTemplate: null,
addMonthlyPriceFromSystemComponents: false
}
],
modelClass: 'Project\\Offer\\Model\\Item',
modelVersion: 1,
viewDiscount: false,
printPricetable: true,
redxTemplateKey: 8,
discountAbsolute: 150,
discountRelative: 0,
termsAndConditions: null,
discountDescription: '',
offerItemKeyTemplate: null,
printGlobalPricetable: false,
printMonthlyPricetable: true,
printTermsAndConditions: false,
printGlobalMonthlyPricetable: false
}
],
title: 'Abschnitt 1',
modelClass: 'Project\\Offer\\Model\\Section',
modelVersion: 1,
viewDiscount: false,
redxTemplateKey: 7,
discountAbsolute: 300,
discountRelative: 0,
discountDescription: '',
offerSectionKeyTemplate: null
}
],
modelClass: 'Project\\Offer\\Model\\Structure',
modelVersion: 1
}
);
@Injectable()
export class FileDatabase {
dataChange = new BehaviorSubject<OfferTree[]>([]);
get data(): OfferTree[] { return this.dataChange.value; }
constructor() {
this.initialize();
}
initialize() {
const dataObject = JSON.parse(TREE_DATA);
const data = this.buildFileTree(dataObject, 0);
this.dataChange.next(data);
}
buildFileTree(obj: {[key: string]: any}, level: number): OfferTree[] {
return Object.keys(obj).reduce<OfferTree[]>((accumulator, key) => {
const value = obj[key];
const node = new OfferTree();
node.name = key;
if (value != null) {
if (typeof value === 'object') {
node.children = this.buildFileTree(value, level + 1);
} else {
node.id = value;
node.name = key;
}
}
return accumulator.concat(node);
}, []);
}
}
@Component({
selector: 'app-tree',
templateUrl: './tree.component.html',
styleUrls: ['./tree.component.sass'],
providers: [FileDatabase]
})
export class TreeComponent implements OnInit {
treeControl: FlatTreeControl<OfferTreeFlatNode>;
treeFlattener: MatTreeFlattener<OfferTree, OfferTreeFlatNode>;
dataSource: MatTreeFlatDataSource<OfferTree, OfferTreeFlatNode>;
@Output() messageEvent = new EventEmitter();
constructor(private database: FileDatabase) {
this.treeFlattener = new MatTreeFlattener(this.transformer, this.getLevel,
this.isExpandable, this.getChildren);
this.treeControl = new FlatTreeControl<OfferTreeFlatNode> (this.getLevel, this.isExpandable);
this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
database.dataChange.subscribe(data => this.dataSource.data = data);
console.log('This is from Constructor');
console.log(database);
console.log('Constructor End');
}
transformer = (node: OfferTree, level: number) => {
return new OfferTreeFlatNode(!!node.children, node.name, level, node.id);
}
private getLevel = (node: OfferTreeFlatNode) => node.level;
private isExpandable = (node: OfferTreeFlatNode) => node.expandable;
private getChildren = (node: OfferTree): Observable<OfferTree[]> => observableOf(node.children);
hasChild = (_: number, nodeData: OfferTreeFlatNode) => nodeData.expandable;
ngOnInit() {
}
sendMessage( node: OfferTree) {
this.messageEvent.emit(node);
}
}
当前,它正在将所有字段从JSON提取到Tree。我的问题是我想从带有正确子节点的JSON中仅提取标题和文本字段。
我该如何解决这个问题?