Data relationships in Mobx

Mobx without a framework

by amindunited

HTML

<script src="https://npmcdn.com/[email protected]/lib/mobx.umd.js"></script>
<body>
  <div id="mount">
    <div id="taskListView">
      <h2>
        Tasks List
      </h2>
    </div>
    <div id="taskCreatorView">
      <h2>
        Add A Task
      </h2>
      <input type="text" id="task_name" name="task_name" placeholder="Name"/>
      <!--
      <input type="text" id="relationships" name="relationships" placeholder="Relationships"/>
      -->
      <input type="text" id="dependencies" name="dependencies" placeholder="Dependencies"/>
      <button>
        Add
      </button>
    </div>
  </div>
</body>

CSS

ul {
  list-style-type: none;
  margin: 0px;
  padding: 0px;
}
#mount {
  display: flex;
}
#taskListView, #taskCreatorView {
  width: 50%;
  background-color: #efefef;
  border: solid 1px #363636;
  border-radius: 3px;
  padding: 3% 3% 10% 3%;
}

#taskListView > ul > li {
  padding: 3px 6px;
  margin-top: 2%;
  margin-bottom: 2%;
  border: solid 1px rgba(127, 127, 127, 0.2);
  border-radius: 3px;
}
ul > div { font-weight: bold; }
li {
  padding-left: 1em;
}
.x {
  float: right;
}

Babel + JSX

const {observable, computed, autorun} = mobx;
const TASK_IDS = [100, 101, 102];

class Task {
	id = null;
	name = null;
  relationships = [];
  dependencies = [];
}
/*
 * Declare an object store
 * (just a list of tasks)
 */
class Store {
	@observable tasks = [
  	{id: 100, name:'placeholder 1'},
    {id: 101, name:'placeholder 2', dependencies:[100]},
    {id: 102, name:'placeholder 3', dependencies:[100, 101]}
  ];
  getTaskById (id) {
  	return this.tasks.filter((obj) => { console.log('getTaskById', obj, obj.id ,'==', id); return obj.id == id; });
  }
}

/*
 * Display a list of tasks
 * (listens to and redraws list when it updates)
 */
class TaskListView {
  constructor(store) {
  	this.store = store;
  	this.tasks = store.tasks;
    this.redrawTemplate();
    //This is where the magic happens: OBSERVE!
    this.tasks.observe(()=>{
      this.redrawTemplate();
    });
  }
  
  addEventListeners() {
  	//this.removeEventListeners();
    let ul = document.querySelector('#taskListView > ul');
    ul.addEventListener('click', (e) => {
    	console.log('remove click', e.target.getAttribute('data-task'));
      let data = e.target.getAttribute('data-task');
    	this.removeTask(JSON.parse(data));
    });
  }
  
  removeEventListeners() {
  	let ul = document.querySelector('#taskListView > ul');
  	ul.removeEventListener();
  }
  
  createListElement(tag, elmText) {
  	let element = document.createElement(tag);
    let innerElm = document.createElement('div');
    innerElm.innerHTML = elmText;
    element.appendChild(innerElm);
    return element;
  }
  
  drawTasks (tasksArr, parent) {
  	console.log('tasksArr', tasksArr);
    tasksArr.forEach((obj, index) => {
    	console.log('forEach', obj);
      
      let displayText = obj.id + ': ' + obj.name;
    	let elm = this.createListElement('li', displayText );
      let closeButton = document.createElement('button');//<button class="x">X</button>';
      closeButton.innerHTML = "X";
     ...