• בלוג
  • היכרות עם Stimulus.js

היכרות עם Stimulus.js

30/08/2018

פריימוורקים לפיתוח צד-לקוח מתפרסמים בהמוניהם ובאמת שאני האחרון להתרגש מעוד פריימוורק חדש שיפתור את כל בעיות העולם. ובכל זאת היה משהו בסטימולוס שמשך אותי להסתכל פעם שניה ובסוף גם לשלב אותו באיזה פרויקט צד. הנה כמה דוגמאות שאולי יעשו גם לכם חשק

1. שלום עולם

הרעיון של סטימולוס הוא לתת לכם מקום מסודר לכתוב את קוד ה JavaScript שלכם, מעין כתיב מבוסס קומפוננטות אבל בלי כל הבלאגן של פריימוורקים אמיתיים והרבה יותר קרוב ל jQuery. הנה דוגמת שלום עולם בסיסית מהאתר שלהם.

  <div data-controller="hello">
    <input data-target="hello.name" type="text" data-action="input->hello#sayHi>
    <p>Hello <span data-target="hello.result" />
  </div>
const application = Stimulus.Application.start()

application.register("hello", class extends Stimulus.Controller {
    static get targets() {
        return [ "name", "result" ]
    }

    sayHi(ev) {
        this.resultTarget.textContent = ev.target.value;
    }
})

וכמובן לייב בקודפן:

מה היה לנו כאן? בצד השלילי בהשוואה ל jQuery יש לנו דרך ממש מעייפת וארוכה להעתיק טקסט משדה input לפיסקה שאחריו. הרי את אותו הדבר היינו יכולים לקבל בשורה אחת של jQuery:

$('input').on('input', function(ev) {
  $('span[data-target="hello.result"]').text(ev.target.value);
})

ובכל זאת לסטימולוס היה ייתרון אחד על פני הגירסא הקצרה והוא הסגירה של הקוד ב Controller. בגירסא של סטימולוס הרבה יותר קל לשנות את ה HTML או את ה JavaScript כשהדרישות ישתנו, בגלל שכל הממשק בין ה HTML ל JavaScript מוגדר בצורה מפורשת - בצד ה JavaScript באמצעות הפונקציה:

    static get targets() {
        return [ "name", "result" ]
    }

ובצד ה HTML באמצעות הגדרת data-target לאלמנטים המתאימים לדוגמא:

<span data-target="hello.result" />

סטימולוס מוסיפה תחום הגדרה לקוד jQuery רגיל שהיינו כותבים.

2. תיבות טקסט מסונכרנות

בואו נראה הרחבה קטנה של התוכנית הפעם יש 5 תיבות טקסט שבכולן תמיד יהיה כתוב אותו הטקסט. קוד ה HTML:

<div data-controller="hello">
    <input data-target="hello.name" type="text" data-action="input->hello#sync">
    <input data-target="hello.name" type="text" data-action="input->hello#sync">
    <input data-target="hello.name" type="text" data-action="input->hello#sync">
    <input data-target="hello.name" type="text" data-action="input->hello#sync">
    <input data-target="hello.name" type="text" data-action="input->hello#sync">
</div>

קוד ה JavaScript:

const application = Stimulus.Application.start()

application.register("hello", class extends Stimulus.Controller {
    static get targets() {
        return [ "name" ]
    }

    sync(ev) {
        $(this.nameTargets).val(ev.target.value);
    }
})

וכמובן לייב בקודפן:

הפעם שילבתי גם jQuery ויש לנו קוד שבנוי משורת קוד אחת בדיוק כמו שהייתי כותב ב jQuery בעולם הישן, עם התוספת של תיחום לרכיב בודד שאנחנו מקבלים מסטימולוס. חדי העין ביניכם יכלו לשים לב שיש לי מספר תיבות עם השם name - וזה ממש בסדר כי סטימולוס מכניס את כולן לאותו מערך ו jQuery יודע לקבל מערך ולשנות את כל האלמנטים בו בפקודה אחת.

בזכות התיחום קל מאוד להרחיב את הדוגמא לשתי קבוצות של תיבות טקסט מסונכרנות וכל מה שצריך זה לשנות את ה HTML בלי לגעת ב JavaScript:

3. דוגמא אחרונה: משחק תפוס ת'אדום

עוד דוגמא אחת לפני שניפרד מסטימולוס היא משחקון תפוס ת'אדום. לחיצה על הכפתור האדום נותנת לכם שתי נקודות ולחיצה על כל כפתור אחר מורידה 2 נקודות. קוד ה JavaScript של המשחק הוא בסך הכל:

const application = Stimulus.Application.start()

application.register("redspotter", class extends Stimulus.Controller {
  static get targets() {
    return [ "winner", 'square', "score" ]
  }

  connect() {
    this.shuffle();
    $(this.element).on('click', '.square', this.play.bind(this));
  }

  play(ev) {
    const score = Number(this.scoreTarget.textContent);
    if (ev.target.classList.contains('winner')) {
      this.scoreTarget.textContent = score + 2;
    } else {
      this.scoreTarget.textContent = score - 2;
    }

    this.shuffle();
  }

  shuffle() {
    const winner = Math.floor(Math.random() * this.squareTargets.length);
    $('.square').removeClass('winner');
    $('.square').eq(winner).addClass('winner');
  }
})

ואת המבנה של כמה כפתורים יש ואיזה מהם אדום ואם רוצים יותר מלוח משחק אחד וכו' קובעים רק ב HTML:

<div data-controller="redspotter">
  <p>
  Score: <span data-target="redspotter.score">0</span>
  </p>
  <div data-target="redspotter.square" class='square winner'></div>
  <div data-target="redspotter.square" class='square'></div>
  <div data-target="redspotter.square" class='square'></div>
  <div data-target="redspotter.square" class='square'></div>
  <div data-target="redspotter.square" class='square'></div>
  <div data-target="redspotter.square" class='square'></div>
</div>

מוזמנים לשחק בקודפן:

4. האם סטימולוס יתאים גם לכם?

זה תלוי. אם אתם מלאי געגועים לימים הישנים והטובים בהם שורת jQuery היתה פותרת לכם את כל הבעיות ויודעים טוב לנווט בין jQuery ל DOM API ומרגישים בנוח בעבודה ישירה עם העמוד אני חושב שסטימולוס יכול להיות תוספת טובה ל jQuery כי הוא מוסיף תחום הגדרה ומבליט את הממשק בין ה HTML ל JavaScript.

מצד שני אם אתם רגילים לסיבוכים של Angular או React ואוהבים לכתוב תבניות בצד הלקוח ויישומי Single Page כנראה שסטימולוס יהיה קטן עליכם.

הכל תלוי בהעדפות שלכם ובפרויקט.