HTML 사용자 정의 요소에 메시지 버스가 없습니다. (보통 마이크로 프런트엔드)
12556 단어 htmllearningwebdevjavascript
예상한 방식을 이해하기 전에, 사용자 정의 이벤트를 포착하고 구독 구성 요소에 직접 보내는 '메시지 버스' 스크립트를 만들었습니다.이것은 정말 엉망진창이다.모든 읽기 전용 속성과 vanillajavascript는 일부 내용을 깊이 있게 복제할 수 없기 때문에 이벤트를 처리하기 어려울 뿐만 아니라, 나는 하나의 구성 요소의 사용자 정의 이벤트 이름을 모든 수신 구성 요소에 하드코딩합니다.
정확한 해결 방안은 사실상 비대칭적이다.하나의 구성 요소가 사용자 정의 이벤트를 발표합니다. 원소 속성과 달리, 그룹과 대상 등 복잡한 유효 하중을 받아들입니다.receiver 구성 요소가 자바스크립트 방법을 공개했습니다. 이 방법은 일반 파라미터를 통해 유효 부하를 받아들일 수 있습니다.수신자 구성 요소에 EventListener를 추가하지 않으며, 발송자 구성 요소는 다른 요소의 방법을 호출하지 않습니다.
이런 설정은 완전히 결합되어 있기 때문에, 맨 윗부분의 접착 코드가 필요하다.나는 이 접착제 코드를 몇 차례 교체했는데, 최소한의 코드부터 시작하여 일을 순조롭게 진행시킨 후에, 무엇을 하든지 절충 방안을 즉시 찾았다.
다음은 내가 생각해 낼 수 있는 구성 요소를 협동하여 일할 수 있는 절대적으로 가장 적은 코드이다.브라우저에서 목록을 조회할 수 없고, '모든 사용자 정의 이벤트' 에 탐지기를 추가할 수 없기 때문에 모든 사용자 정의 이벤트 형식을 포함하는 그룹에서 시작합니다.(나는 곧 그 작은 문제로 돌아갈 것이다.)
['drilldown', 'pieChartInit', 'showTip', 'hideTip']
.forEach(et =>
document.addEventListener(et, ev =>
document.querySelectorAll(`[${ev.type}]`).forEach(el =>
el?.[el.getAttribute(ev.type)]?.bind(el)(ev))));
이것은 이렇게 적혀 있습니다. "사용자 정의 이벤트 형식마다 맨 위에 이벤트 탐지기를 추가합니다. 이벤트 중 하나가 발생할 때, 처리 프로그램은 이벤트 형식과 같은 속성을 가진 모든 요소를 찾을 것입니다. 이 속성과 같은 문자열 값은 이 요소를 호출하는 방법명입니다. 이 방법의 매개 변수는 항상 이벤트 자체이며, 부하를 포함합니다."예를 들어 사용자 정의 이벤트 형식인'drilldown'에 대해 코드는'drilldown'속성
<some-component drilldown="method">
이 있는 모든 요소를 찾고 이 속성의 값인'method'를 호출할 방법으로 사용합니다: someComponent.method(event)
.이전에 get Attribute가 빈 문자열을 발견했을 때, 나는 백업 계획을 세웠다. 예를 들어
<some-component drilldown>
, 그것도 '깊이 들어가기' 를 호출 방법으로 사용했지만, 이것은 두 구성 요소를 너무 꽉 연결시켰다.또한 속성은 항상 소문자/대소문자를 구분하지 않고javascript는 대소문자를 구분하지 않기 때문에'깊이'방법을 찾을 수 없어 혼동을 초래한다.코드를 사용할 구성 요소에 대해 사용자 정의 거품 이벤트를 만들어야 합니다.매번 스케줄러 전화를 할 때마다 추가로 타자를 쳐야 하는데, 이것은 매우 짜증스럽다.따라서 이벤트의 포획 단계에서 포획하고 모든 스케줄링 코드를 정리할 수 있도록 세 번째 인자'true '를ddEvent Listener에 추가합니다.
['drilldown', 'pieChartInit', 'showTip', 'hideTip']
.forEach(et =>
document.addEventListener(et, ev =>
document.querySelectorAll(`[${ev.type}]`).forEach(el =>
el?.[el.getAttribute(ev.type)]?.bind(el)(ev)), true));
내가 시도한 또 다른 방법은 최소한의 코드를 사용하지 않고, 상기 코드를'library.js' 파일에 넣는 것이다.미니멀리즘을 그다지 강조하지 않는 상황에서 나는 생활의 질적 특징을 약간 증가시켰다.이벤트 형식 앞에 'on' 을 붙였기 때문에 이벤트 'drilldown' 은 속성 'on Drilldown' 에 포착되어 더 읽을 수 있는 HTML: <some-component onDrilldown="method">
을 생성합니다.초기 문자열 그룹에 프로그램의 모든 사용자 정의 이벤트 형식을 표시하는 것을 피하기 위해'register '함수를 추가했습니다.마지막으로, 나는'say '함수를 추가했다. 구성 요소는 이 함수를 사용하여 본 컴퓨터 문법보다 더 간결하게 사용자 정의 이벤트를 할당할 수 있고, 본 컴퓨터 문법은 이벤트 형식도 등록하여 (등록하지 않았을 경우) 구성 요소가 시작할 때register를 호출하는 것을 피할 수 있다.const registeredCustomEventTypes = {};
export function say(element, customEventType, detail) {
if (!registeredCustomEventTypes[customEventType])
register(customEventType);
element.dispatchEvent(new CustomEvent(customEventType, { detail }));
}
export function register(customEventType) {
document.addEventListener(customEventType, go, true);
registeredCustomEventTypes[customEventType] = true;
}
function go(event) {
const onEventType = 'on' + event.type;
document.querySelectorAll(`[${onEventType}]`).forEach(element =>
element?.[element.getAttribute(onEventType) || onEventType]?.bind(element)(event));
}
나는 이 라이브러리 코드를 사용하는 것이 나쁜 생각일 수도 있다고 생각한다.HTML 사용자 정의 요소의 장점 중 하나는 진정한 단일 파일 구성 요소를 만드는 것이다. 제로 의존성, 심지어 라이브러리에 의존하지 않는다.도서관을 포함해서 우리는 이런 우세를 잃었다.그 다음으로, 이것은 그와 함께 사용하는 모든 구성 요소가 이 라이브러리 코드를 알고, 적어도 레지스터 함수와 상호작용을 하도록 요구한다. 레지스터 함수는 공공 중개를 통해서라도 구성 요소를 다시 결합시키기 시작한다.모든 Require 호출을 최고급 접착 코드에 넣어서 피할 수 있지만, 첫 번째 코드 예시에서, 이것은 문자열 그룹의 더 자세한 버전일 뿐입니다.이상하게도 브라우저에 사용자 정의 이벤트에 사용할 내장된 이벤트 등록표가 없습니다.가장 간단한 코드라도 원시 이벤트를 처리 프로그램에 전달함으로써 구성 요소를 이벤트의 부하에서 필요한 정보를 추출하는 것이 아니라, 원하는 형식으로 방법에 필요한 내용만 제공할 수 있다.이런 미세한 데이터 변환은 구성 요소의 개성을 완벽하게 보존하여 모든 사건과 방법이 유일무이하게 되었다.
만약 모든 이벤트가 방법tie가 유일하다면, 모든 처리 프로그램은 유일하다. 이것은 루트에 있는 모든addevent Listener가 유일하다는 것을 의미한다. 이것은 통용되는 메시지 버스가 있을 수 없다는 것을 의미한다.이런 버스가 어떤 형식을 사용하든지 간에, 모든 구성 요소가 인터페이스에 부합되도록 은밀하게 요구한다. 마치 나의 라이브러리와 같다.네.여기서 못 이겨.
document.addEventListener('drilldown', e => {
document.querySelectorAll('chart-legend').repopulate(e.detail.fieldName, e.detail.newData);
});
document.addEventListener('drilldown', e => {
document.querySelectorAll('field-selector').refresh({
Old: e.detail.fieldName,
New: e.detail.meta.fields.map(f=>f.name),
});
});
// etc., forever
Reference
이 문제에 관하여(HTML 사용자 정의 요소에 메시지 버스가 없습니다. (보통 마이크로 프런트엔드)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ronnewcomb/missing-the-message-bus-in-html-custom-elements-and-micro-frontends-in-general-1582텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)