web-dev-qa-db-ja.com

Typescriptでオブジェクトを別のオブジェクトにマップします

PrimeNGを使用してTreeNodeオブジェクトにマップしてツリーに表示したいロールオブジェクトがあります。役割オブジェクトは次のようなものです(写真にも示されています)

role: [
id: ....
name: ....
   description: ....
   roles[]: .....
]

role object

ツリーノードオブジェクトの構造は次のとおりです。

{
"data": 
[
    {
        "label": "Documents",
        "data": "Documents Folder",
        "expandedIcon": "fa-folder-open",
        "collapsedIcon": "fa-folder",
        "children": [{
                "label": "Work",
                "data": "Work Folder",
                "expandedIcon": "fa-folder-open",
                "collapsedIcon": "fa-folder",
                "children": [{"label": "Expenses.doc", "icon": "fa-file-Word-o", "data": "Expenses Document"}, {"label": "Resume.doc", "icon": "fa-file-Word-o", "data": "Resume Document"}]
            },
            {
                "label": "Home",
                "data": "Home Folder",
                "expandedIcon": "fa-folder-open",
                "collapsedIcon": "fa-folder",
                "children": [{"label": "Invoices.txt", "icon": "fa-file-Word-o", "data": "Invoices for this month"}]
            }]
    },
    {
        "label": "Pictures",
        "data": "Pictures Folder",
        "expandedIcon": "fa-folder-open",
        "collapsedIcon": "fa-folder",
        "children": [
            {"label": "barcelona.jpg", "icon": "fa-file-image-o", "data": "Barcelona Photo"},
            {"label": "logo.jpg", "icon": "fa-file-image-o", "data": "PrimeFaces Logo"},
            {"label": "primeui.png", "icon": "fa-file-image-o", "data": "PrimeUI Logo"}]
    },
    {
        "label": "Movies",
        "data": "Movies Folder",
        "expandedIcon": "fa-folder-open",
        "collapsedIcon": "fa-folder",
        "children": [{
                "label": "Al Pacino",
                "data": "Pacino Movies",
                "children": [{"label": "Scarface", "icon": "fa-file-video-o", "data": "Scarface Movie"}, {"label": "Serpico", "icon": "fa-file-video-o", "data": "Serpico Movie"}]
            },
            {
                "label": "Robert De Niro",
                "data": "De Niro Movies",
                "children": [{"label": "Goodfellas", "icon": "fa-file-video-o", "data": "Goodfellas Movie"}, {"label": "Untouchables", "icon": "fa-file-video-o", "data": "Untouchables Movie"}]
            }]
    }
]

}

 data.roles.forEach((role, index) => {
        //this.roleTree.label = role.Name;
        //this.roleTree.data = role.ID;

        let treeNode: TreeNode = {
            label: role.Name,
            data: role

        }

        this.treeNodes.Push(treeNode);
        console.log(role);
        console.log(index);

    });

しかし、「role」の「roles」をtreeNodeの「children」にマップしようとすると、このコードは複雑すぎるようです。 this のような例を見たことがありますが、同じフィールド名をマッピングしています。

私はTypesriptを初めて使用しますが、ロールの「ラベル」にマップするフィールド名(名前など)を指定することで、ロールを持つロールオブジェクトを子を持つtreeNodeに変換する回避策はありますか?

コード例をいただければ幸いです。

3
sam

さて、私はあなたが使用しているRoleTreeNodeタイプについて100%確信がありません。これがあなたの質問のコードに基づく私の推測です。

Roleには気になるプロパティがいくつかありますが、注意が必要なのはrolesプロパティです。これは、Roleオブジェクトの配列を意味していると思います。

_interface Role {
  id: string;
  name: string;
  description: string;
  roles: Role[];
}
_

同様に、TreeNodeにはいくつかのプロパティがありますが、注意が必要なのは、childrenオブジェクトの配列であるTreeNodeプロパティです。また、TreeNodedataの型でジェネリックであると想定しています。この場合、_TreeNode<Role>_を実行します。つまり、dataプロパティはRoleオブジェクトになる:

_interface TreeNode<T> {
  label: string;
  data: T;
  expandedIcon?: string;
  collapsedIcon?: string;
  children: TreeNode<T>[];
}
_

Ifこれらが正しい場合は、次のroleToTreeNode()関数を使用して、Roleオブジェクトを_TreeNode<Role>_オブジェクトにマップできます。

_function roleToTreeNode(role: Role): TreeNode<Role> {
  return {
    label: role.name,
    data: role,
    children: role.roles.map(roleToTreeNode)
  };
}
_

_children:_行は、関数の有効な部分です。_role.roles_配列を取得し、各Role要素を_TreeNode<Role>_にマッピングします。これがroleToTreeNode()関数は行います。つまり、roleToTreeNode()は、それ自体を呼び出す再帰関数です。

これは意味がありますか?お役に立てば幸いです。幸運を!

7
jcalz