2016-05-17 4 views
7

を追加します。私は、次のディレクティブを使用しています:角度は、私はこのような階層データを持つ親の属性値

app.directive('tree', function (hierarchyService, logger, $timeout) { 
    return { 
     scope: { 
      data: '=' 
     }, 
     restrict: 'E', 
     replace: true, 
     template: '<div>' + 
      '<table class="table table-striped table-hover">' + 
      ' <thead>' + 
      '  <tr>' + 
      '   <th class="col-md-6">Account name</th>' + 
      '  </tr>' + 
      '  </thead>' + 
      '  <tbody><tr collection data="data" /></tbody>' + 
      ' </table>' + 
      '</div>' 
    }; 
}); 

app.directive('collection', function() { 
    return { 
     restrict: "A", 
     replace: true, 
     scope: { 
      data: '=', 
      depth: '@' 
     }, 
     template: '<member ng-repeat="member in data" member="member" depth="{{depth}}" />', 
     link: function (scope, element, attrs) { 
      scope.depth = parseInt(scope.depth || 0); 
     } 
    } 
}); 

app.directive('member', function($compile) { 
    return { 
     restrict: "E", 
     replace: true, 
     scope: { 
      depth: '@', 
      member: '=' 
     }, 
     template: '<tr ng-class="{selected: member.selected}">' + 
      '<td>' + 
      ' <span ng-show="depth > 0" style="width: {{depth * 16}}px; display: inline-block;"></span> {{member.name}}' + 
      '</td>' + 
      '</tr>', 
     link: function (scope, element, attrs) { 
      scope.depth = parseInt(scope.depth || 0); 

      if (angular.isArray(scope.member.children) && scope.member.children.length > 0) { 
       var el = angular.element('<tr collection data="member.children" depth="{{newDepth}}" />'); 
       scope.depth = parseInt(scope.depth || 0); 
       scope.newDepth = scope.depth + 1; 
       $compile(el)(scope); 

       // Flatten hierarchy, by appending el to parent 
       element.parent().append(el); 
      } 
     } 
    } 
}); 

問題は、親スコープからlink方法、depthから追加されたコレクションにnewDepthに追加される、ということです。その結果、レベル3ノードのdepthの値はdepth="3 2 1 "になります。

depthの継承を無効にする方法はありますか?

また、私はcollectionmemberディレクティブでfalseにreplaceを変更すると、意図したとおりの深さは動作しますが、その後、HTMLが無効であること、気づきました。

+0

は、あなたがあなたのケースのためにplunkerやフィドルを提供してもらえますか? –

+0

@SpartakLalajここにあります:https://plnkr.co/edit/CE2z5WeU41H4qJQQ73B7?p=preview – Krzysztof

+0

深度属性を削除し、等号記号で宣言しました。数字が正しいようです。それが正しい結果であるかどうか試してみてください! –

答えて

0

子ノードに同じスコープを使用して、その奇妙な連結を引き起こすことを、と思われます。これは簡単なことですが、それは判明したように、新しい子スコープが各子に必要です。リンク機能は、次のようになります。

link: function (scope, element, attrs) { 
    if (angular.isArray(scope.member.children) && scope.member.children.length > 0) { 
     // Create isolated child scope, pass `scope` as parent 
     var childScope = scope.$new(true, scope); 
     childScope.depth = parseInt(scope.depth || 0) + 1; 
     childScope.member = scope.member; 

     var el = angular.element('<tr collection data="member.children" depth="{{depth}}" />'); 

     // use child scope 
     $compile(el)(childScope); 

     // Flatten hierarchy, by appending el to parent 
     element.after(el); 
    } 
} 

Plunk:https://plnkr.co/edit/xhJwfV?p=preview

私もreplaceが廃止されていることを、SOおよびAPIの上の他の場所を発見したので、実際にそれを使用することshould't。だから、交換することなく、それは次のようになります。

app.directive('tree', function() { 
    return { 
     restrict: 'E', 
     template: '<div>' + 
      '<table class="table table-striped table-hover">' + 
      ' <thead>' + 
      '  <tr>' + 
      '   <th class="col-md-6">Account name</th>' + 
      '   <th class="col-md-1">Depth</th>' + 
      '  </tr>' + 
      '  </thead>' + 
      '  <tbody row data="data"></tbody>' + 
      ' </table>' + 
      '</div>', 
     link: function (scope, element, attrs) { 
      scope.data = [ 
       { 
       name: 'Root', 
       children: [ 
        { 
        name: 'Level 1', 
        children: [ 
         { 
         name: 'Level 2', 
         children: [ 
          {name: "Level 3"}, 
          {name: "Level 3 -1"} 
         ] 
         } 
        ] 
        }, 
        { 
        "name": "Level 1-1" 
        } 
       ] 
       } 
      ]; 
     } 
    }; 
}); 

app.directive('row', function() { 
    return { 
     restrict: "A", 
     scope: { 
      data: '=', 
      depth: '@' 
     }, 
     template: '<tr cells ng-repeat="member in data" member="member" />', 
     link: function (scope, element, attrs) { 
      scope.depth = parseInt(scope.depth || 0); 
     } 
    } 
}); 

app.directive('cells', function($compile) { 
    return { 
     restrict: "A", 
     scope: { 
      data: '=', 
      depth: '@', 
      member: '=' 
     }, 
     template: //'<tr ng-class="{selected: member.selected}">' + 
      '<td>' + 
      ' <span ng-show="depth > 0" style="width: {{depth * 16}}px; display: inline-block;"></span> {{member.name}}' + 
      '</td>' + 
      '<td>{{depth}}</td>', 
      //'</tr>', 
     link: function (scope, element, attrs) { 
      if (scope.member && angular.isArray(scope.member.children) && scope.member.children.length > 0) { 
       var childScope = scope.$new(true); 
       childScope.depth = parseInt(scope.depth || 0) + 1; 
       childScope.data = scope.member.children; 

       var el = angular.element('<tr cells ng-repeat="member in data" member="member" depth="{{depth}}" />'); 

       $compile(el)(childScope); 

       // Flatten hierarchy, by appending el to parent 
       element.after(el); 
      } 
     } 
    } 
}); 

Plunker:https://plnkr.co/edit/j3YcuQ?p=preview

2

時には、はるかに単純な解決法が優れていることがあります。サービス中のツリー状の構造を平坦化し、ng-repeatを使用して新しい構造を繰り返す方が良いです。 https://plnkr.co/edit/CiFGZYi6NdH8ZFDiAyPz?p=preview

もっと簡単なコード。理解しにくい指示文は必要ありません。また、deprecatedのように、ディレクティブにreplaceを使用しないでください。

スタイルを動的に設定するには、ng-styleディレクティブを使用する必要があります。

var app = angular.module('app', []); 

app.factory('treeFlatting', function() { 
    function flattenTree(tree, depth) { 
    depth = depth || 0; 

    return tree.reduce(function (rows, node) { 
     var row = { 
     name: node.name, 
     depth: depth, 
     }; 
     var childrenRows = angular.isArray(node.children) ? 
     flattenTree(node.children, depth + 1) : []; 

     return rows.concat(row, childrenRows); 
    }, []); 
    } 

    return flattenTree; 
}); 

app.directive('tree', function (treeFlatting) { 
    return { 
     restrict: 'E', 
     replace: true, 
     template: '<div>' + 
      '<table class="table table-striped table-hover">' + 
      ' <thead>' + 
      '  <tr>' + 
      '   <th class="col-md-6">Account name</th>' + 
      '   <th class="col-md-1">Depth</th>' + 
      '  </tr>' + 
      '  </thead>' + 
      '  <tbody>'+ 
      '   <tr ng-repeat="row in rows">'+ 
      '    <td ng-style="{\'padding-left\': (16 * row.depth) + \'px\'}">{{row.name}}</td>'+ 
      '    <td>{{row.depth}}</td>'+ 
      '   </tr>'+ 
      '  </tbody>' + 
      ' </table>' + 
      '</div>', 
     link: function (scope, element, attrs) { 
      scope.data = [ 
       { 
       name: 'Root', 
       children: [ 
        { 
        name: 'Level 1', 
        children: [ 
         { 
         name: 'Level 2' 
         } 
        ] 
        } 
       ] 
       } 
      ]; 

      scope.rows = treeFlatting(scope.data).filter(function (row) { 
      return row.depth > 0; 
      }); 
     } 
    }; 
}); 
+0

私は専用のツリーコンポーネントを使うこともできますが、それは意味がありません。この振る舞いは少なくとも私の意見ではおかしなことですが、意図していれば(今のところ無効にすることもできます)、バグであれば今に行きたいと思います。私が最も奇妙なことは、フラグをfalseに置き換えると、うまくいきます(しかし、マークアップが乱れている)ということです。 – Krzysztof

+0

私はそれを近く見ることはできませんでしたが、その問題は '@'と文字列の連結を使用することにあると思います。 btw。なぜあなたはそのような変わった方法でそれをしましたか? – sielakos

+0

私は角張っているだけで遊んでいます、そして、その行動は私が期待したものではありません。私はその問題に遭遇して以来、私は解決策を知りたいです。 – Krzysztof

関連する問題