저는 지금 뭔가 효과가 있습니다. 위 질문에 대한 제 의견에 설명 된대로 작동합니다. 요컨대, ng-repeat를 기반으로하는 두 개의 사용자 정의 지시문을 사용하고 있습니다. 첫 번째는 깊이를 나타 내기 위해 class 속성에 리터럴 값이있는 플랫 테이블 구조를 만듭니다. 두 번째 지시문은 해당 심도 정보를 사용하여 적절한 횟수만큼 패딩 요소를 반복합니다. 두 repeater는 html에 대한 제한 사항/종속성을 최소화하기 위해 transclusion을 사용합니다. 유일한주의 사항은 두 번째 리피터가 깊이 정보를 필요로한다는 것입니다. 깊이 정보는 DOM 내의 조상입니다.
다음은 HTML 템플릿 내 질문에 설명 된 구조의 나무 테이블을 생성하는 모습입니다 :
<table class="treetable" style="width: 40%;">
<tr class="treetable-node" my-repeat="item in things"
my-repeat-children="children">
<td>
<span my-repeat-padding class="treetable-node-indent"></span>
{{ item.name }}
</td>
<td>
{{ item.type }}
</td>
</tr>
</table>
나는
this 예에 내 사용자 지정 중계기를 기반으로. 내 것이 다른 점은 "children"속성을 지정할 수 있고 지시문 논리가 각 항목의 해당 속성을 확인하고 거기에있는 경우 재귀 적으로 강등된다는 것입니다. 모든 새 요소를 동일한 부모에게 첨부하지만 나에게 플랫 구조.
아마도 매우 비효율적이며 일부 최적화를 사용할 수 있습니다. 링크의 코드와 같이 변경 사항이있을 때 모든 것을 다시 작성합니다.
myApp.directive("myRepeat", function($parse) {
return {
restrict: "A",
replace: true,
transclude: "element",
link: function (scope, element, attrs, controller, transclude) {
match = attrs.myRepeat.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/);
itemName = match[1];
collectionName = match[2];
childCollectionName = attrs["myRepeatChildren"];
parentElement = element.parent();
elements = [];
scope.$watchCollection(collectionName, function(collection) {
var i, block, childScope;
if (elements.length > 0) {
for(i=0; i<elements.length; i++) {
elements[i].el.remove();
elements[i].scope.$destroy();
};
elements = [];
}
var buildHtml = function(parent, itemList, depth=0) {
for (var i=0; i<itemList.length; i++) {
childScope = scope.$new();
childScope[itemName] = itemList[i];
transclude(childScope, function(clone) {
parentElement.append(clone);
block = {};
block.el = clone;
block.scope = childScope;
block.el.addClass("depth-" + depth);
elements.push(block);
});
/*Recurse if this item has children,
adding the sub-elements to the same
parent so we end up with a flat list*/
if(childCollectionName in itemList[i]) {
buildHtml(parentElement,
itemList[i][childCollectionName],
depth+1);
}
}
}
for (i=0; i<collection.length; i++) {
buildHtml(parentElement, collection);
}
});
}
};
});
두 번째 것은 약간 해킹입니다. 그것은 또한 transcluding 중계기입니다. 깊이 클래스 속성에 대해 DOM에서 위쪽으로 검색하고 깊이 값을 파싱 한 다음 여러 번 그 자체를 부모 앞에 추가합니다. 따라서 그것은 첫 번째 지시어에 의해 설정된 깊이 등급에 전적으로 의존합니다. 아마 그것을하는 더 좋은 방법이 있습니다. 이 시계는 순수하게 화장품이기 때문에 시계 등을 설치하는 것을 신경 쓰지 않았습니다.
myApp.directive("myRepeatPadding", function($parse) {
return {
restrict: "A",
replace: true,
transclude: "element",
terminal: true,
link: function (scope, element, attrs, controller, transclude) {
var getDepth = function(element) {
classes = element.attr("class");
if (classes) {
match = classes.match(/depth-([\d+])/);
if(match.length > 0) {
return match[1];
} else {
return getDepth(element.parent());
}
} else {
return getDepth(element.parent());
}
}
depth = getDepth(element);
for (var i=0; i<depth; i++) {
transclude(scope, function(clone) {
element.parent().prepend(clone);
block = {};
block.el = clone;
block.scope = scope;
elements.push(block);
});
}
}
};
});
완벽하지는 않지만 개선하는데 시간을 투자해야합니다. 나는 내가 제작하는 HTML이 내가 원하는 모습을 얻는 가장 좋은 방법인지는 모르겠다. 그러나 html 템플릿을 적당하게 보이게 유지하면서 원하는 방식으로 렌더링한다.
어떤 이유로 든이 테이블이 필요합니까? 편집을 허용하기 위해 [angular-json-tree] (https://github.com/awendland/angular-json-tree)와 같은 지시문을 확장 해 볼 수 있습니다. – haxxxton
여러 열이 필요합니다. 나는 간략하게하기 위해 그들을 보여주지 않았다. –
추가 열을 사용하여 달성하고자하는 목표는 무엇입니까? :) 편집/삭제/복제 버튼 : – haxxxton