मेरे पास एक 2डी सरणी है जो एक बोर्ड का प्रतिनिधित्व करती है जिसे आरंभ किया जाता है और App.svelte पर संभाला जाता है। फिर मैं इसे एक Board घटक में भेजता हूं, जो प्रत्येक सेल को एक Cell घटक के रूप में प्रस्तुत करता है, प्रत्येक सेल को बाइंड करके (क्योंकि यह स्वयं को बदल सकता है)।

ऐप एक डीएफएस खोज एल्गोरिदम का अनुकरण करता है, इसलिए एक निश्चित बिंदु पर एल्गोरिदम 2 डी सरणी पर चलता है, और इसे अपडेट करता है, जो App.svelte पर पंजीकृत होता है।

मैं परिवर्तन को Board और फलस्वरूप प्रत्येक Cell घटकों में कैसे पंजीकृत कर सकता हूं? क्या मुझे Board को फिर से प्रस्तुत करने के लिए बाध्य करना होगा?

वर्तमान में जब 2D सरणी App पर बदल जाती है तो पूरा बोर्ड अपनी मूल स्थिति में वापस आ जाता है (हालाँकि बोर्ड में विशेष सेल होते हैं)

छोटा App.svelte:

<script>
  import Board from "./Components/Board.svelte";
  import { beforeUpdate } from "svelte";

  var board = [];

  beforeUpdate(() => {
    const rows = LIMIT;
    const columns = LIMIT;
    board = new Array(rows).fill(0).map(() => new Array(columns).fill(0));
  });

  function startSearch() { // Board changes in here
    });
  }
  /**
   * State indexes:
   * 0 = white - Not, but can traverse
   * 1 = blue - Starting point
   * 2 = aquamarine - current cell
   * 3 = orange - End point
   * 4 = gray - wall
   * 5 = black - finished traversing
   */
</script>

<div>
    <Board {board} />
</div>

Board:

<script>
  export let board;
  import Cell from "./Cell.svelte";  
</script>


<div class="board">
  {#each board as row, i}
    <div class="row">
      {#each board[i] as cell, j}
        <Cell bind:cell={cell} {i} {j} />
      {/each}
    </div>
  {/each}
</div>

Cell:

<script>
  export let cell = 0,
    i,
    j;
  let cellDiv;
  import { start, end, state, mouse } from "../stores.js";
  import { afterUpdate } from "svelte";
  let _state = state;
  state.subscribe((val) => {
    _state = val;
  });
  afterUpdate(() => {
    //After updating check if my state changed
    if ($start !== cellDiv && cell === 3) {
      //Check if I'm still endpoint
      cell = $end === cellDiv ? 3 : 0;
      cellDiv.style.backgroundColor = cellToClass();
    }
    if ($end !== cellDiv && cell === 1) {
      //Check if I'm still starting-point
      cell = $start === cellDiv ? 1 : 0;
      cellDiv.style.backgroundColor = cellToClass();
    }
    if (cell === 0 || cell === 5 || cell === 2) {
      cellDiv.style.backgroundColor = cellToClass();
    }
    if (cell === 5 || cell === 2) {
      console.log("x");
      cellDiv.style.backgroundColor = cellToClass();
    }
  });
  function clickHandler() {
    if (_state === 1) {
      //Start point
      if ($end === cellDiv) $end = null;
      $start = cellDiv;
      cell = 1;
    } else if (_state === 3) {
      //End point
      if ($start === cellDiv) $start = null;
      $end = cellDiv;
      cell = 3;
    } else if (_state === 4) {
      //Barriers
      if ($start === cellDiv) $start = null;
      if ($end === cellDiv) $end = null;
      cell = 4;
    }
    cellDiv.style.backgroundColor = cellToClass();
  }
  function handleMouse() {
    if ($mouse && _state === 4) clickHandler();
  }
  function cellToClass() {
    switch (cell) {
      case 0:
        return "white";
      case 1:
        return "dodgerblue";
      case 2:
        return "mediumaquamarine";
      case 3:
        return "rgb(240, 63, 10)";
      case 4:
        return "gray";
      case 5:
        return "black";
      default:
        return "black";
    }
  }
</script>

<div
  class="cell"
  id="{i} {j}"
  bind:this={cellDiv}
  on:mousemove={handleMouse}
  on:click={clickHandler} />

पूर्ण असंबद्ध भंडार

0
Nix 12 नवम्बर 2020, 21:53

1 उत्तर

सबसे बढ़िया उत्तर

मैं परिवर्तन को बोर्ड में कैसे दर्ज कर सकता हूं और इसके परिणामस्वरूप सेल के प्रत्येक घटक में? क्या मुझे बोर्ड को फिर से प्रस्तुत करने के लिए बाध्य करने की आवश्यकता है?

एर... ठीक है, हाँ। यदि आप पुन: प्रस्तुतीकरण को ट्रिगर नहीं करते हैं, तो आपको कुछ भी परिवर्तन नहीं दिखाई देगा। री-रेंडर यहां भ्रामक है, हालांकि, स्वेल्ट क्या कर रहा है, इसके संबंध में एक "अपडेट" शायद अधिक सटीक होगा। एक चल रहा Svelte ऐप (यानी एक बार संकलित) अनिवार्य रूप से राज्य में परिवर्तन से सीधे पथ को जानता है (वेरिएबल दें ...) को संबंधित डीओएम तत्व (ओं) को अद्यतन/पुन: निर्मित करने की आवश्यकता है, या राज्य के टुकड़े जिन्हें होने की आवश्यकता है पुनर्गणना। Svelte में एक "री-रेंडर" का अर्थ कभी भी घटक स्तर पर भी, सब कुछ पुनर्गणना या पुन: बनाना नहीं है।

वर्तमान में जब ऐप पर 2D सरणी बदल जाती है तो पूरा बोर्ड अपनी मूल स्थिति में वापस आ जाता है (हालाँकि बोर्ड में विशेष सेल होते हैं)

ऐसा इस कोड के कारण है:

  beforeUpdate(() => {
    const rows = LIMIT;
    const columns = LIMIT;
    board = new Array(rows).fill(0).map(() => new Array(columns).fill(0));
  });

यह हर बार App परिवर्तन में कुछ चलता है। यह वह नहीं है जो आप चाहते हैं। यह तो ज्यादा है!

आपको शायद इसे केवल एक बार चलाने की आवश्यकता है:

  let board = new Array(rows).fill(0).map(() => new Array(columns).fill(0))

यदि आप इसे विन्यास योग्य बनाने का इरादा रखते हैं, तो आप इसे प्रतिक्रियाशील बना सकते हैं:

  export let rows = LIMIT
  export let columns = LIMIT

  $: board = new Array(rows).fill(0).map(() => new Array(columns).fill(0))

आपको लगता है कि onMount एक बेहतर घटना हो सकती है, लेकिन मुझे नहीं लगता कि आप यहां भी यही चाहते हैं। , क्योंकि onMount चलने से पहले, आपके पास खाली बोर्ड के साथ एक बेकार रेंडर चक्र होगा। नाटकीय नहीं, यकीनन, लेकिन फिर भी, इस मामले में अपने चर को तुरंत शुरू करना थोड़ा बेहतर है।

beforeUpdate हुक भी आपके App घटक में स्टोर ऑटो-सब्सक्रिप्शन छोटी गाड़ी बना रहा है, और आपको $start सिंटैक्स का उपयोग करने से रोक रहा है।

1
rixo 13 नवम्बर 2020, 01:23