전자 모험: 33회: 사건 루트
                                            
                                                
                                                
                                                
                                                
                                                
                                                 33904 단어  electronsveltejavascript
                    
불행히도, 이것은 우리 파일 관리자에게 아직 충분하지 않다.
파일 관리자 이벤트
이벤트는 여러 개의 원본에서 오고 여러 구성 요소에 영향을 주며 이벤트 유형과 목표 사이에 동적 매핑을 할 수 있습니다.사용자가 새 디렉토리를 만들려면 여러 가지 방법이 있습니다.
그래서 많은 논리가 있는데, 만약 우리가 그것을 전체 코드 라이브러리에 덮어 씌우면, 그것은 커다란 혼란이 될 것이다.대부분의 사건을 보내고 그 사건을 어떻게 처리할지 결정하는 중심 위치가 있어야 한다.
이것은 로컬 이벤트를 동시에 가질 수 없다는 것을 의미하지 않는다. 예를 들어 단추를 누르거나 필드에 입력한 내용을 하나의 구성 요소로 관리할 수 있다.
우리는 Svelte stores, Svelte context, 단순
EventBus 클래스를 사용하여 이 모든 것을 관리할 것입니다.단순 이벤트 라우팅 응용
우리는 그것을 파일 관리자 프로그램에 집적할 것이지만, 먼저 더 작은 것에서 실험을 하는 것이 더욱 쉽다.
다음은 애플리케이션입니다.
src/EventBus。js
첫 번째 행사 버스.이것은 매우 간단한 자바스크립트 대상이다.실례를 만들고 이벤트 처리 프로그램을 등록합니다.
이벤트 목표, 이벤트 이름, 임의의 매개 변수를 받아들이는
emit 방법이 있습니다.그것 또한 * 특수 이벤트 처리 프로그램을 처리하여 특정 처리 프로그램이 없는 어떤 이벤트도 처리한다.현재 특정한 처리 프로그램이나 적당한 목표가 없는 이벤트를 조용히 삭제하지만, 아마도 우리는
console.log에 경고를 해야 할 것 같습니다.이것은 용례에 달려 있다.export default class EventBus {
  constructor() {
    this.callbacks = {}
  }
  handle(target, map) {
    this.callbacks[target] = { ...(this.callbacks[target] || {}), ...map }
  }
  emit(target, event, ...details) {
    let handlers = this.callbacks[target]
    if (handlers) {
      if (handlers[event]) {
        handlers[event](...details)
      } else if (handlers["*"]) {
        handlers["*"](event, ...details)
      }
    }
  }
}
src/App。날씬한 틀
먼저 템플릿과 스타일을 살펴보겠습니다. 여기에는 특별한 것이 없기 때문입니다.
<div class="app">
  <Box id="box-1" />
  <Box id="box-2" />
  <Box id="box-3" />
  <Box id="box-4" />
  <Footer />
</div>
<Keyboard />
<style>
  :global(body) {
    margin: 0;
  }
  .app {
    background-color: hsl(180,100%,20%);
    font-family: monospace;
    color: #333;
    height: 100vh;
    width: 100vw;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr auto;
    gap: 10px;
  }
</style>
idHTMLDOMid과는 아무런 관계가 없으며, 실제적으로 모든 상자가 이벤트 시스템에 자신을 표시한다.Keyboard는 DOM을 생성하지 않고 일부 이벤트 처리 프로그램을 메인 창에 추가하는 데 자주 사용되지 않는 구성 요소입니다.src/App。섬세한 문자
이제 재미있는 부분으로 넘어가겠습니다.
<script>
  import { writable } from "svelte/store"
  import { setContext } from "svelte"
  import Box from "./Box.svelte"
  import Footer from "./Footer.svelte"
  import Keyboard from "./Keyboard.svelte"
  import EventBus from "./EventBus.js"
  let activeBox = writable("box-1")
  let clipboard = writable("")
  let eventBus = new EventBus()
  setContext("app", {activeBox, clipboard, eventBus})
</script>
activeBox 현재 활성 상태인 상자와 clipboard 클립보드의 내용을 표시한다.우리는 또한 EventBus 실례를 만들어서 이벤트 처리 프로그램을 등록할 수 있다.컨텍스트 및 스토리지
그리고 우리는 그것들을 상하문 대상의 키
app 아래에 저장할 것이다.세 가지 다른 컨텍스트를 사용할 수도 있습니다.  setContext("activeBox", activeBox)
  setContext("clipboard", clipboard)
  setContext("eventBus", eventBus)
왜 우리는 상점을 가치가 아니라 상하문에 두어야 합니까?어셈블리를 작성할 때 컨텍스트를 읽고 자동으로 업데이트되지 않습니다.그래서 이것은 정말 쓸모가 없다.
  let activeBox = "box-1"
  let clipboard = ""
  setContext("app", {activeBox, clipboard, eventBus})
  let activeBox = "box-1"
  let activeBoxSubscriptions = []
  function changeActiveBox(newValue) {
    activeBox = newValue
    for (let callback of activeBoxSubscriptions) {
      callback(newValue)
    }
  }
  function subscribeToActiveBoxChanges(callback) {
    activeBoxSubscriptions.push(callback)
  }
  setContext("app", { activeBox, subscribeToActiveBoxChanges, ... })
activeBox부터 changeActiveBox까지.응, 구성 요소가 파괴되었을 때 구독을 취소할 수 있도록 메커니즘을 추가해야 해.이런 구독, 구독 취소, 리셋은 값을 바꾸는 등 조작이 번거롭기 때문에 Svelte는 매장을 단축키로 한다.
구성 요소의 어느 곳에서든
$activeBox 을 사용하면, Svelte는 자동으로 구독 activeBox 을 시도하고, 이러한 리셋을 통해 업데이트 $activeBox 변수를 업데이트합니다.필요할 때 구독을 취소합니다.이 변수는 올바른 반응성 변수이기 때문에 모든 변경 사항이 템플릿에 자동으로 적용되거나, 모든 반응성 문장에 적용됩니다.
우리가 상하문, 저장, 그리고
EventBus 각종 구성 요소에서 사용하는 예를 통해 더욱 뚜렷해져야 한다.src/App。가벼운 이벤트 처리 프로그램
응용 프로그램에는 두 개의 이벤트 처리 프로그램이 있습니다.
quit (F10) 창을 닫고, changeBox 어떤 상자가 활성 상태인지 변경합니다.activeBox.set(id) 저장소를 업데이트한 후 모든 구독자App 구성 요소 자체를 포함하여 특별한 점이 없음)에서 리셋을 실행하고 모든 구독자에 설정$activeBox합니다.  function quit() {
    window.close()
  }
  function changeBox(id) {
    activeBox.set(id)
  }
  eventBus.handle("app", {quit, changeBox})
"activeBox" 에 어댑터 리셋을 등록한 다음 현재 실제 활동 상태의 상자에 다시 보내는 것이다.  function emitToActiveBox(...args) {
    eventBus.emit($activeBox, ...args)
  }
  eventBus.handle("activeBox", {"*": emitToActiveBox})
src/바닥글.날씬하다
응, 너무 많아.다행히도 프로그램의 나머지 부분은 상당히 간단하다.아래는 바닥글입니다.
<script>
  import { getContext } from "svelte"
  let { eventBus } = getContext("app")
</script>
<footer>
  <button on:click={() => eventBus.emit("app", "changeBox", "box-1")}>Box 1</button>
  <button on:click={() => eventBus.emit("app", "changeBox", "box-2")}>Box 2</button>
  <button on:click={() => eventBus.emit("app", "changeBox", "box-3")}>Box 3</button>
  <button on:click={() => eventBus.emit("app", "changeBox", "box-4")}>Box 4</button>
  <button on:click={() => eventBus.emit("activeBox", "cut")}>F1 Cut</button>
  <button on:click={() => eventBus.emit("activeBox", "copy")}>F2 Copy</button>
  <button on:click={() => eventBus.emit("activeBox", "paste")}>F3 Paste</button>
  <button on:click={() => eventBus.emit("app", "quit")}>F10 Quit</button>
</footer>
<style>
  footer {
    grid-column-start: span 2;
    text-align: center;
  }
  button {
    font-size: 24px;
    font-weight: bold;
    color: inherit;
    background-color: hsl(180,100%,40%);
    font-family: inherit;
  }
</style>
eventBus 실례를 얻은 다음, 호출된 각종 단추 eventBus.emit(target, event, arguments) 를 누르기만 하면 된다.어떻게 그것을
app 자체 또는 정확한 상자에 전달하는지, 스크립트와 무관하다.src/키보드.날씬하다
<script>
  import { getContext } from "svelte"
  let { eventBus } = getContext("app")
  function handleKey({key}) {
    if (key.match(/^[1234]$/)) {
      eventBus.emit("app", "changeBox", `box-${key}`)
    }
    if (key.match(/^[a-zA-Z]$/)) {
      eventBus.emit("activeBox", "letter", key)
    }
    if (key === "Backspace") {
      eventBus.emit("activeBox", "backspace", key)
    }
    if (key === "F1") {
      eventBus.emit("activeBox", "cut")
    }
    if (key === "F2") {
      eventBus.emit("activeBox", "copy")
    }
    if (key === "F3") {
      eventBus.emit("activeBox", "paste")
    }
    if (key === "F10") {
      eventBus.emit("activeBox", "quit")
    }
  }
</script>
<svelte:window on:keydown={handleKey} />
window 에 자신을 연결했기 때문에 좀 심상치 않을 수도 있다.마찬가지로 상하문에서
eventBus를 얻고 keydown 이벤트를 처리하며 누르는 키에 따라 정확한 목표를 향해 정확한 이벤트를 보냅니다.이 구성 요소는 처리 수정 키 (예를 들어 Cmd-C 또는 Ctrl-C) 로 확장될 수 있으며, 사용자가 변경할 수 있도록 플랫폼에 특정한 논리가 필요할 수도 있습니다.심지어vim키 귀속일지도 몰라요.모두 한곳에 있다.
src/Box。날씬하다
다른 곳에 이렇게 많은 논리가 있기 때문에
Box 구성 요소는 상당히 간단하다.먼저 템플릿과 스타일:<div class="box" class:active on:click={onClick}>
  {text}
</div>
<style>
.box {
  font-size: 48px;
  font-weight: bold;
  background-color: hsl(180,100%,30%);
  display: flex;
  justify-content: center;
  align-items: center;
}
.box.active {
  background-color: hsl(180,100%,40%);
}
</style>
text 변수가true이면 active 클래스가 있고, 클릭하면 active 방법이 호출됩니다.<script>
  import { getContext } from "svelte"
  let { eventBus, activeBox, clipboard } = getContext("app")
  export let id
  let text = "A"
  function onClick() {
    eventBus.emit("app", "changeBox", id)
  }
  function letter(key)  {
    text += key
  }
  function backspace() {
    text = text.slice(0, -1)
  }
  function cut() {
    clipboard.set(text)
    text = ""
  }
  function copy() {
    clipboard.set(text)
  }
  function paste() {
    text = $clipboard
  }
  eventBus.handle(id, {letter, backspace, cut, copy, paste})
  $: active = ($activeBox === id)
</script>
onClick 실례에 긴 사건을 등록했다.이벤트 처리 프로그램은 이곳에서 매우 간단하다.여기에 작은 기교가 하나 있는데
eventBus가 변화할 때마다active 표지는 반응적인 변화를 일으킨다.모든 구독과 리셋 등은 스웨트가 처리하기 때문에 우리는 아무것도 할 필요가 없다.결실
결과는 다음과 같습니다.
 
 나는 그것이 상당히 깨끗한 체계 구조로 코드가 매우 간결하고 (Redux와 같지 않으며) 더욱 복잡한 상황을 처리하기 쉽게 확장된다고 생각한다.
Svelte 상점과 상하문은 Svelte의 표준 부분이지만,
activeBox 단지 내가 이 프로그램을 위해 만든 것일 뿐이다.당신은 다른 방식으로 그것을 설계할 수 있습니까?그렇다면 다른 방법을 댓글로 알려주세요.
다음 회에서 프로그램 메뉴를 추가합니다.
여느 때와 마찬가지로all the code for the episode is here.
Reference
이 문제에 관하여(전자 모험: 33회: 사건 루트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/taw/electron-adventures-episode-33-event-routing-586p텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)