stimulus初体验

Author Avatar
Peipei Wong 10月 22, 2018
  • 在其它设备中阅读本文章

demo

stimulus
ts作为js的超集,应用率也是非常广泛,在github上看到一个有趣的框架,于是想着从hello word走起,看完栗子有,我尝试写一个列表…

<div data-controller="content-loader" data-content-loader-url="/message.html" data-content-loader-refresh-interval="5000"></div>

  <h1>list controller</h1>
  <div data-controller="list" data-list-initial='["name"]'>
    <div>
      <input type="text" data-target="list.text" value="hello1">
      <button data-action="click->list#add">add</button>
    </div>
    <div data-target="list.items"></div>
  </div>
import { Controller } from 'stimulus';

export default class extends Controller {
  static targets = ['text', 'items', 'item'];

  connect() {
    this.getInitialItems();
  }

  get items() {
    return this.items;
  }

  set items(newItems) {
    this.items = newItems;
    this.render(newItems);
  }

  get text() {
    return this.textTarget.value;
  }

  getInitialItems() {
    try {
      this.items = JSON.parse(this.data.get('initial'));
    } catch(e) {
      this.items = [];
      console.error(e)
    }
  }

  render(items) {
    this.itemsTarget.innerHTML = items.reduce((acc, item, index) => {
      return acc + `<p data-target="list.item"><span>${item}</span><button data-id="${index}" data-action="click->list#deleteItem">delete</button></p>`;
    }, '');
  }

  add() {
    this.items = this.items.concat(this.text);
  }

  deleteItem(event) {
    const targetIndex = event.currentTarget.dataset.id;
    const newItems = [
      ...this.items.slice(0, targetIndex),
      ...this.items.slice(targetIndex + 1)
    ];
    this.items = newItems;
  }
}

看起来非常good,于是开始运行,发现死循环了,检查了代码没发现错误,尝试debugger发现程序一直在执行set操作,很纳闷,没执行set呀。找机会问了哟哟,他告诉我,在set中尝试给this.item赋值意味着你在set调用set本身,于是乎,死循环了…

get items() {
    return this._items;
  }

  set items(newItems) {
    this._items = newItems;
    this.render(newItems);
  }

修改成以上代码可以正常工作。

思考:

1、如果以上面的方式进行,我觉得还不如做成面向对象中的set/get….这只是我个人的想法

  1. 将html写在js中一点都不优雅,我找到了一个demo,它提供一个更好的方式。
  2. 使用stimulus,思维方式和传统的js相似
  3. 在stimulus中,数据和元素不是一一对应的,所以在deleteItem中直接删除元素并且改变items的方式会不会比通过数据去改变dom更好一点?虽然二随一变会容易出bug,但是考虑到列表可能会很多,删除一个元素比重新渲染整个列表代价小很多吧(2019.4.9更新,不确定😂)…..