var AppState = function (initialState) { this.data = initialState; this.callbacks = []; }; AppState.prototype.get = function () { return this.data; }; AppState.prototype.set = function (newState) { this.data = newState; this.callbacks.forEach(function (cb) { cb.call(null, newState); }); }; AppState.prototype.addListener = function (cb) { this.callbacks.push(cb); }; var PostsList = function (container, data) { this.container = container; this.setData(data); }; PostsList.prototype.render = function () { var ul = document.createElement('ul'); var lis = this.data.map(function (post) { var li = document.createElement('li'); li.innerText = post.title; ul.appendChild(li); }); while (this.container.hasChildNodes()) { this.container.removeChild(this.container.lastChild); } this.container.appendChild(ul); }; PostsList.prototype.setData = function (newData) { this.data = newData; this.render(); }; var firstDataset = [{ title: 'My new blog post' }, { title: 'Managing state' }]; var secondDataset = [{ title: 'Updated blog post' }, { title: 'New state' }]; var datasets = [firstDataset, secondDataset]; var appState = new AppState(firstDataset); var postsList = new PostsList(document.getElementById('main'), appState.get()); appState.addListener(function(newData) { postsList.setData(newData); }); setInterval(function () { var idx = Math.round(Math.random(1)); appState.set(datasets[idx]); }, 500);
<div id="main"></div>