В настоящее время я переписываю дерево файлов в приложении AngularJS. Способ реализации дерева файлов в конце состоит из FileInfo
s, DirectoryInfo
s и DirectoryEntry
s. По сути, файлы и каталоги могут быть подключены к любому количеству каталогов, которые вам нравятся, потому что каталоги просто содержат записи, указывающие на определенный файл или идентификатор каталога (даже на родительский идентификатор, так что вы можете идти по кругу). Я бы сказал, что это не идеальный API, но что сделано, то сделано.
Причина, по которой я даже поднимаю бэкэнд-API, заключается в том, что он полностью связан с реализацией внешнего интерфейса. По сути, каждый Node
имеет идентификатор, указывающий на файл или каталог, которому он соответствует, но сам по себе он не может сказать , где узел находится в иерархии. Таким образом, при выполнении операций, таких как добавление / удаление / переименование записей каталога, вы должны знать не только имя / идентификатор записи, но и родительский элемент. Чтобы сделать это, мы могли бы передавать массивы узлов как с родителем, так и с дочерним узлом (что мы обычно делали), или сохранять сопоставление узлов с их родителями, но оба эти решения довольно грязные. В идеале реализация во внешнем интерфейсе должна представлять собой двусвязный граф, в котором каждый узел каталога имеет список своих дочерних элементов, а у каждого из этих дочерних элементов есть ссылка на родительский элемент
. Я хорошо знаю, что вы можете вызватьscope.$watch(expression, listener, true)
для рекурсивного просмотра всех свойств объекта. Тем не менее, это никогда не вызывается для чего-либо, связанного с нашим классом Node
. Тем не менее, только со следующим рекурсивным шаблоном AngularJS начинает подавляться ошибками cyclic object value
.
<!-- Recursive node template -->
<script type="text/ng-template" id="tree-pane_node.html">
<div style="padding-left: {{ level * 24 }}px" ng-click="$ctrl.navigateTo(node)">
<a ng-click="$ctrl.toggleOpen(node); $event.stopPropagation()">
<md-icon class="mdi mdi-24px" ng-class="node.isOpen ? 'mdi-chevron-down' : 'mdi-chevron-right'"></md-icon>
<md-icon class="mdi mdi-24px mdi-{{ node.icon }}"></md-icon>
</a>
<span>{{ node.name }}</span>
</div>
<div ng-if="node.isOpen">
<div ng-repeat="node in node.children | filter:{isDir: true} | orderBy:'name'" ng-init="level = level + 1">
<div ng-include="'tree-pane_node.html'"></div>
</div>
</div>
</script>
<!-- Kick off the recursion with the top-level (special) directories -->
<div ng-repeat="node in ::$ctrl.topLevelDirectories" ng-init="level = 0" ng-include="'tree-pane_node.html'"></div>
Примечание: Я опустил классы CSS, а также некоторые обратные вызовы выражений, такие как ng-right-click
для краткости.
Нет привязок шаблона к node.parent
где-либо в приложении. Так почему я получаю cyclic object value
ошибок? По умолчанию AngularJS отслеживает привязки шаблонов? Если да, можно ли это отключить? Как я уже говорил ранее, в настоящее время я переписываю часть кода в дереве файлов и знаю, что эта ошибка возникает в результате хранения родительских ссылок на узлах, а не из-за чего-то другого вприложение.
Я заметил, что ошибка происходит от JSON.stringify()