2017-12-25 11 views
4

ノードのノードが下位であるかどうか、ノードがユーザーの役割と互換性があるかどうかを調べるために、配列を繰り返し処理します。Typescript - 関数の戻り値を使用する際に問題があります

Iしかし「someArray」は関数の戻り値であり、Iは、アレイ内のノードの各値を取得する「(someArrayのエントリを聞かせ)のための」使用かもしれないと思った:

public menuList(): any { 
    return [ 
     // SCHEDULER 
     { 
      route: ["", "scheduler"], 
      name: "scheduler", 
      moduleId: PLATFORM.moduleName("../components/scheduler/scheduler"), 
      title: "scheduler", 
      nav: true, 
      settings: { 
       icon: "user", 
       roles: ["Employee", "Admin"], 
       pos: "left" 
      } 
     }, 

     // CLIENTS 
     { 
      route: "clients", 
      name: "clients", 
      moduleId: PLATFORM.moduleName("../components/clients/clientList/clientList"), 
      title: "Clients", 
      nav: true, 
      settings: { 
       icon: "user", 
       roles: ["Employee", "Admin"], 
       pos: "left", 
       nav: [ 
        { 
         route: "clients/ClientsList", 
         name: "clientList", 
         moduleId: PLATFORM.moduleName("../components/clients/clientList/clientList"), 
         href: "#clients/clientsList", 
         title: "Client List", 
         settings: { 
          icon: "list", 
          roles: ["Employee", "Admin"], 
         } 
        }, 
        { 
         settings: { 
          roles: ["Employee", "Admin"], 
          divider: true, 
         } 
        }, 
        { 
         route: "clients/create", 
         name: "newClient", 
         moduleId: PLATFORM.moduleName("../components/clients/newClient/newClient"), 
         href: "#clients/Create", 
         title: "Create Client", 
         settings: { 
          icon: "user", 
          roles: ["Employee", "Admin"], 
         } 
        } 
       ] 
      } 
     }, 

     // JOBS 
     { 
      route: "jobs", 
      name: "jobs", 
      moduleId: PLATFORM.moduleName("../components/jobs/jobsList"), 
      title: "Jobs", 
      nav: true, 
      settings: { 
       icon: "list", 
       roles: ["Employee", "Admin"], 
       pos: "left" 
      }, 
     }, 

     // ACCOUNTING 

     // Accounting - 1st level route WITH SUBROUTES 
     { 
      route: "accounting", 
      name: "accounting", 
      moduleId: PLATFORM.moduleName("../components/accounting/ledgerEnquiry/ledgerEnquiry"), 
      title: "Accounting", 
      nav: true, 
      settings: { 
       icon: "usd", 
       roles: ["Employee", "Admin"], 
       pos: "left", 
       nav: [ 
        { 
         title: "Creditor Cost Invoices", 
         icon: "tasks", 
         nav: true, 
         roles: ["Employee", "Admin"], 
         settings: { 
          nav: [ 
           { 
            title: 'Creditor Payments', 
            icon: 'usd', 
            roles: ["Employee", "Admin"], 
            settings: { 
             nav: [ 
              { 
               route: "accounting/creditorCostInvoices/payments/paymentsRegister", 
               name: "paymentsRegister", 
               moduleId: PLATFORM.moduleName("../components/accounting/creditorCostInvoices/payments/paymentsRegister/paymentsRegister"), 
               href: '#accounting/creditorCostInvoices/payments/paymentsRegister', 
               title: 'Payments Register', 
               settings: { 
                icon: 'list', 
                roles: ["Employee", "Admin"] 
               } 
              }, 
              { 
               settings: { 
                roles: ["Employee", "Admin"], 
                divider: true, 
               } 
              }, 
              { 
               route: "accounting/creditorCostInvoices/payments/creditorPromptPayments", 
               name: "promptPayments", 
               moduleId: PLATFORM.moduleName("../components/accounting/creditorCostInvoices/payments/creditorPromptPayments/creditorPromptPayments"), 
               href: '#accounting/creditorCostInvoices/payments/creditorPromptPayments', 
               title: 'Creditor Prompt Payments', 
               settings: { 
                icon: 'usd', 
                roles: ["Employee", "Admin"] 
               } 
              }, 
              { 
               route: "accounting/creditorCostInvoices/payments/payOutstandingCreditorInvoices", 
               name: "payments", 
               moduleId: PLATFORM.moduleName("../components/accounting/creditorCostInvoices/payments/payOutstandingCreditorInvoices/payOutstandingCreditorInvoices"), 
               href: '#accounting/creditorCostInvoices/payments/payOutstandingCreditorInvoices', 
               title: 'Pay Outstanding Creditor Invoices', 
               settings: { 
                icon: 'edit', 
                roles: ["Employee"/*, "Admin"*/] 
               } 
              }, 
             ], 
            } 
           }, 
          ] 
         } 
        }, 
       ] 
      } 
     } 
    ] 
} 

スケジューラであります1つのノードとクライアントは別のものですが、クライアントは3つのノードを持つ配列を持っています。

これを繰り返して、新しい配列を作成します。ノードのいずれかがロールの値を満たさない場合、元の配列の深度構造を維持したままノードを削除します。したがって、menuList( )ロール設定が "Admin"を持っていて、それがそのノードを無視して、 "Admin"を持つノードだけでフィルタリングされた配列を取得しない場合、このチェックを繰り返します。

モンスター "forループ"をネストした "forループ"で試してみましたが失敗しました。

私は今、私がlet entry of someArrayを使うだろうと思ったが、私はエラーを取得しています:

Error TS2349 (TS) Cannot invoke an expression whose type lacks a call signature. Type 'any[]' has no compatible call signatures

ない...しかし

をこの問題を解決する方法がわからベースのこの配列をフィルタリングするスマートな方法はありますまだ構造を維持しながらrole.includes( "Admin")などで?

UPDATE

私は最終的に私はそれを行うためのより良い、より簡潔な方法の多くがあるだろうと思いますが、この作業を取得するために管理。

私は、次のノードに移動する前に各ノードを完全に扱うという考えを持ちました。これを行うために、レベルごとに自分自身を呼び出す再帰関数を使用しました。

public userMenu(userName: string, userRole: string): any { 
    let finishedRoleCheckedMenu = Array(); 
    let userMenuElements = Array(); 
    let returnedElement = {} as any; 


    for (const key in this.menuList()) { 
     returnedElement = this.processElement(this.menuList()[key], userRole); 

     if (returnedElement !== 'undefined') { 
      userMenuElements.push(returnedElement); 
     } 
    } 

    for (let count = 0; count < this.routeMenuItems.length; count++) { 
     if (!this.routeMenuItems[count].settings.divider) { 
      userMenuElements.push(this.routeMenuItems[count]); 
     } 
    } 

    return userMenuElements; 
} 


processElement(element: any, userRole: string) { 
    let testedElement = {} as any; 
    let settingsElement = {} as any; 
    let navElements = Array(); 
    let navElement = {} as any; 

    if (element.settings.roles.includes(userRole)) { 

     for (const key in element) { 
      if (key === "settings") { 

       for (const settingsKey in element[key]) { 
        if (settingsKey === "nav") { 

         for (const navKey in element[key][settingsKey]) { 

          navElement = this.processElement(element[key][settingsKey][navKey], userRole); // recursive call. 

          if (navElement !== 'undefined') { 
           if (navElement.route) { // Collect only those elements with routes. 
            this.routeMenuItems.push(navElement); // For adding the total routes at the end. 
           } 
           navElements.push(navElement); 
          } 
         } 
         if (navElements.length > 0) { 

          settingsElement[settingsKey] = navElements; 
         } 
        } else { 
         settingsElement[settingsKey] = element[key][settingsKey]; 
        } 
       } 
       testedElement[key] = settingsElement; 
      } else { 
       testedElement[key] = element[key]; 
      } 
     } 

     return testedElement; 
    } else { 
     return 'undefined'; 
    } 
} 
+0

MenuItemインターフェイスを作成し、それを返すようにします。それでも、あなたの配列の内部に互換性のない要素があることを意味するので、エラーはおそらく消えません。 – c69

答えて

1

コンパイラが呼び出し元コードについて不平を言っています。具体的には、返された配列で行うことを計画しています。この理由は、戻り値の型を "any"として指定したためです。おそらく戻り値の型がより適切かもしれません。

配列をフィルタリングする限り、正しい軌道に乗っていると思いますが、地図やマップ/縮小パターンを使用してコードを少しきれいにすることができます。

+0

戻り値の型を配列として構造化するにはどうすればいいですか?引数は必要ですが、単純な配列ではなくオブジェクト配列です。 "string" numberなどを指定することはできません - 配列オブジェクト要素を指定する方法 – si2030

+0

はい、私の考えでは、私が念頭に置いていたことが最もクリーンであるとベータ・デベロッパーが言ったことの行に沿って何かが起こります。タイプスキームは、タイプスキームがTSで開発するときに本当に興味のあるものの1つでない限り、 – iHazCode

+0

私はこれを動作させ、自分のコードを追加しました。上記の更新のセクションで、その価値は何ですか? – si2030

関連する問題