#javascript #angular
Вопрос:
Предположим, у меня есть следующий JSON :
[{
"id": "main",
"deps": [],
"class": "export class MainClass { constructor() { console.log('I am the main class'); } }"
}, {
"id": "logger",
"deps": ["main"],
"class": "export class MainClass { constructor(main) { console.log('I am the logger : ', main); } }"
}, {
"id": "feat",
"deps": ["main", "logger"],
"class": "export class MainClass { constructor(main, logger) { console.log('I am a feature: ', main, logger); } }"
}]
Как вы можете видеть, JSON содержит
- Идентификатор класса, позволяющий идентифицировать его уникальным способом
- Список зависимостей для класса, которые вводятся в конструктор
- Некоторый код для самого класса
Предположим, я уже могу создавать классы и вводить их зависимости в правильном порядке.
Моя проблема в том, что :
Как я могу построить классы в правильном порядке, чтобы каждая зависимость загружалась правильно ?
(Другими словами, как отсортировать этот массив в правильном порядке)
Мой первоначальный подход состоял в том, чтобы дать «уровень» каждому классу в зависимости от их количества зависимостей. Но это не гарантирует порядок, следовательно, зависимости не определены …
Любая помощь будет очень признательна !
PS : Я использую Angular, отсюда и теги, я не знаю, что еще добавить, поэтому, если я неправильно поставил вопрос, не стесняйтесь редактировать его
ОТРЕДАКТИРУЙТЕ Вот MCVE, чтобы помочь вам протестировать его :
const classes = [{
id: "main",
deps: [],
class: "class MainClass { constructor() { console.log('I am the main class'); } }",
},
{
id: "logger",
deps: ["main"],
class: "class MainClass { constructor(main) { console.log('I am the logger : ', main); } }",
},
{
id: "feat",
deps: ["main", "logger"],
class: "class MainClass { constructor(main, logger) { console.log('I am a feature: ', main, logger); } }",
},
{
id: "levelIssue",
deps: ["feat"],
class: "class levelIssueClass { constructor(feat) { console.log('I depend on feature : ', feat); } }",
},
];
// This is the variable that should have everything sorted
const ordered = classes.sort((a, b) => a.deps.length - b.deps.length);
const instanciated = {};
for (const c of ordered) {
eval('window.module = ' c.class);
const deps = c.deps.map(id => instanciated[id]);
const tmp = new window.module(...deps);
instanciated[c.id] = tmp;
delete window.module;
}
Ответ №1:
Ну, в вашем примере у вас вроде как уже есть «уровень» для каждого класса, если вы рассматриваете deps.length
свойство.
Поэтому, если вы сначала загружаете все свои классы без зависимостей ( deps: []
), То после классов с одной зависимостью и так далее вам просто нужно отсортировать массив таким образом.
[РЕДАКТИРОВАТЬ] Прежде чем вы это сделаете, вы должны сопоставить свой deps
, чтобы получить весь список, чтобы класс был на правильном уровне, прежде чем вы выполните загрузку.
Это выглядело бы примерно так:
const data = [{
id: "main",
deps: [],
class: "class MainClass { constructor() { console.log('I am the main class'); } }",
},
{
id: "logger",
deps: ["main"],
class: "class MainClass { constructor(main) { console.log('I am the logger : ', main); } }",
},
{
id: "feat",
deps: ["main", "logger"],
class: "class MainClass { constructor(main, logger) { console.log('I am a feature: ', main, logger); } }",
},
{
id: "levelIssue",
deps: ["feat"],
class: "class levelIssueClass { constructor(feat) { console.log('I depend on feature : ', feat); } }",
},
];
// map dependencies
const classes = data.map((item) => {
// gets the dependencies from dependencies and concats into one array
const deps = item.deps.concat(item.deps.map(classId => data.find(c => c.id === classId).deps)).flat();
return {
...item,
deps,
};
});
// sort by deps.length
classes.sort((a, b) => (a.deps.length > b.deps.length) ? 1 : -1).forEach((item) => {
// load item
});
Комментарии:
1. Привет, спасибо за ваше предложение, к сожалению, оно работает не так, как задумывалось. Я отредактировал исходное сообщение, чтобы добавить новый класс с одной зависимостью, которая зависит от класса с двумя : зависимость становится неопределенной. Я также добавил MCVE, если вы хотите его протестировать !
2. Я отредактировал свой ответ с предложением карты, проверьте, соответствует ли он вашим потребностям сейчас
![]()