2

この作業コードは、この問題の典型的な解決策のようです。

カテゴリとそのサブカテゴリを保持する多次元配列を取り (深さのレベル数に暗黙の制限はありません)、そこから HTML の順序付けられていないリストを作成し、再帰関数内からページにエコーアウトします。

サブレベルは、_category_list()_ という名前の元のコールバック関数内から、各配列要素の「子」キーの値を array_walk() に再帰的に渡すことによってトラバースされます。

すべての HTML コードが関数の外のテンプレートに存在するように、この出力方法を変更するにはどうすればよいでしょうか?

コードの概要は次のとおりです。

この多次元配列は、複数レベルのカテゴリ ツリーを保持します。

HTML で使用する重要なキーは、「category_id」、「name」、および「children」です。簡単にするために、他のキーは以下の配列から削除されていますが、有用な場合は、'parent_id' と 'level' (レベル 1 から開始) です。

<?php

// the array containing the tree
$categories = array (
  'category_id' => '2',
  'name' => 'Top Category Name',
  'children' => array (
    0 => array (
      'category_id' => '188',
      'name' => 'Category Name',
      'children' => array (
        0 => array (
          'category_id' => '159',
          'name' => 'Category Name',
          'children' => array (),
        ),
        1 => array (
          'category_id' => '160',
          'name' => 'Category Name',
          'children' => array (),
        ),
        2 => array (
          'category_id' => '166',
          'name' => 'Category Name',
          'children' => array (),
        ),
      ),
    ),
    1 => array (
      'category_id' => '4',
      'name' => 'Category Name',
      'children' => array (
        0 => array (
          'category_id' => '141',
          'name' => 'Category Name',
          'children' => array (),
        ),
        1 => array (
          'category_id' => '142',
          'name' => 'Category Name',
          'children' => array (),
        ),
      ),
    ),
  ),
)

?>

.

この次の関数は、HTML 出力の大部分を生成しますが、HTML を内部にロックします。

ただし、関数から直接エコーするのではなく、デザイナーがカスタマイズしやすい方法で、このデータをビュー テンプレートに戻す方法を探しています。

<?php

// separate the HTML from this function,
// passing $v to the view template for handling
function category_list($v, $k){
  switch ($k) {
    case 'category_id':
      echo "<li id="$v">";
      break;
    case 'name':
      echo "$v";
      break;
    case 'children':
      if(count($v) > 0){
        echo "<ul>";
        foreach($v as $k=>$v)
        array_walk($v, 'category_list');
        echo "</ul>";
      }
      echo "</li>";
      break;
  }
}

?>

.

コードの次のブロックは、現在のテンプレート html/php で、array_walk() を介して配列の最初のレベルをトラバースし、上記の再帰関数を参照する呼び出しを含みます。次に、関数自体が、1 つ以上の子を持つより深いカテゴリの再帰と反復を処理します。もちろん、これは典型的なアプローチです。

このコードには、外側のタグだけでなく、すべての HTML タグを含める必要があります。

<ul>
<?php array_walk($tree,'category_list'); ?>
</ul>

.

理想的なソリューション:

ここでの最終目標は、テンプレート デザイナーが再帰関数 (アクセスできない) を作成または変更する必要なく、多次元の各レベルで foreach ループを使用する必要なく、理想的なナビゲーション構造を作成する方法を見つけることです。配列。ソリューションは、特定の深さの制限に結び付けられるべきではありません。

HTML のカスタマイズの例としては、ul/li タグ内に追加の属性を配置したり、CSS で引き戸効果を実現するためにナビゲーションで一般的に使用される span タグなどの出力テキストを新しいタグで囲んだりすることまで、さまざまです。したがって、適切なソリューションは、少なくともこれらのケース シナリオをサポートする必要があると思います。

array_walk() を使用してテンプレートから配列を反復処理しても、コールバック関数が目的の変数をテンプレートに戻してデザイナーの HTML で使用できるように使用できる限り、問題ありません。

理想的には、もし array_walk_recursive() がその反復子が実際に何レベル深いかを知っていれば、この偉業は解決するのがはるかに簡単になると思います. しかし、誰かがその問題の回避策を知らない限り、解決策はまったく異なる可能性があります.

また、ツリーの構築に JavaScript メソッドを使用することも避けたいと考えています。また、スイッチの使用を避ける方法があれば、私も提案を受け付けています。

4

1 に答える 1

1

返したい情報を管理および保存するクラスを作成することを考えたことはありますか。関数は、そのクラスのインスタンスを変更して、最後に塗りつぶされたオブジェクトを返すことができます。

コンテンツはクラス内にカプセル化され、ユーザーがデータを操作および出力するためのすべてのメソッドとユーティリティを作成できます。クラス内にユーティリティ メソッドを記述して、レベル数などを表示することもできます。

私は自分で試したことはありませんが、クラスを使用すると、ユーザーが望むものを改良および拡張することができ、何が起こっているかの内部の詳細を知る必要がないため、ここから始めます。

于 2009-05-21T17:31:02.670 に答える