utils_ui_traverse-component-tree-with-callback.js
/**
* @callback TraverseComponentTreeCallback
* @param {nexacro.Component} component
* 컴포넌트
* @param {TraverseComponentTreeCallbackContext} context
* 유틸성 함수
*/
/**
* @typedef TraverseComponentTreeCallbackContext
* @property {function} stopChildNodeTraversal
* 트리 순회를 중단
*/
/**
* 인수로 받은 컴포넌트의 하위 컴포넌트를 순회하며 callback 함수 호출
* stopChildNodeTraversal() 함수를 호출 하면 해당 컴포넌트 하위 영역 순환을 중단함.
*
* @function traverseComponentTreeWithCallback
* @param {nexacro.Component} comp
* - root 컴포넌트
* @param {TraverseComponentTreeCallback} callback
* - 실행할 콜백함수
* @memberof $f
* @example
* $f.traverseComponentTreeWithCallback(this.div_search, (comp, ctx) => {
* // 모든 컴포넌트의 readonly 속성을 true로 설정
* comp.readonly = true;
*
* // div_exclude라는 이름을 가진 컴포넌트를 만나면
* if (comp.name === "div_exclude") {
* // 해당 컴포넌트의 하위 컴포넌트 순회를 중단
* ctx.stopChildNodeTraversal();
* }
* });
*
*/
export function traverseComponentTreeWithCallback(comp, callback) {
let isStopTraversal = false;
const callbackArgs = {
stopChildNodeTraversal: () => {
isStopTraversal = true;
},
};
callback(comp, callbackArgs);
if (isStopTraversal) return;
if (comp instanceof nexacro.Form) {
Array.from(comp.all).forEach((v) =>
traverseComponentTreeWithCallback(v, callback),
);
} else if (comp instanceof nexacro.Div) {
traverseComponentTreeWithCallback(comp.form, callback);
} else if (comp instanceof nexacro.Tab) {
Array.from(comp.tabpages).forEach((v) =>
traverseComponentTreeWithCallback(v, callback),
);
} else if (comp instanceof nexacro.Tabpage) {
traverseComponentTreeWithCallback(comp.form, callback);
}
}