Skip to content

Instantly share code, notes, and snippets.

@TCotton
Created July 22, 2017 15:30
Show Gist options
  • Save TCotton/86d1ca3726f481acd939edc78b0b6639 to your computer and use it in GitHub Desktop.
Save TCotton/86d1ca3726f481acd939edc78b0b6639 to your computer and use it in GitHub Desktop.
Mode Vew Controller
import { PenguinModel } from './penguinModel';
import { PenguinView } from './penguinView';
interface IPenguinViewModel {
name: string;
imageUrl: string;
size: string;
favoriteFood: string;
previousIndex: number;
nextIndex: number;
index: number;
count: number;
}
class PenguinController {
public penguinModel: any;
public penguinView: any;
constructor(PenguinView, PenguinModel) {
const targetElement = <HTMLElement>document.getElementById('listOfPenguins');
this.penguinView = new PenguinView(targetElement);
this.penguinModel = new PenguinModel(XMLHttpRequest);
}
public initialize() {
this.penguinView.onClickGetPenguin = this.onClickGetPenguin.bind(this);
}
public onClickGetPenguin(event: any) {
const dataset = event.currentTarget.dataset;
const index = Number(dataset.penguinIndex);
this.penguinModel.getPenguin(index, this.showPenguin.bind(this));
}
public showPenguin(penguinModelData) {
const penguinViewModel = {
name: penguinModelData.name,
imageUrl: penguinModelData.imageUrl,
size: penguinModelData.size,
favoriteFood: penguinModelData.favoriteFood,
previousIndex: null,
nextIndex: null,
};
penguinViewModel.previousIndex = penguinModelData.index - 1;
penguinViewModel.nextIndex = penguinModelData.index + 1;
if (penguinModelData.index === 0) {
penguinViewModel.previousIndex = penguinModelData.count - 1;
}
if (penguinModelData.index === penguinModelData.count - 1) {
penguinViewModel.nextIndex = 0;
}
this.penguinView.render(penguinViewModel);
};
}
const controller = new PenguinController(PenguinView, PenguinModel);
controller.initialize();
controller.onClickGetPenguin({ currentTarget: { dataset: { penguinIndex: 0 } } });
export class PenguinModel {
public XMLHttpRequest: XMLHttpRequest;
constructor(XMLHttpRequest: XMLHttpRequest) {
this.XMLHttpRequest = XMLHttpRequest;
}
public getPenguin(index: number, fn: (any) => void) {
const oReq = new XMLHttpRequest();
oReq.onload = function onLoad(event: any) {
const ajaxResponse = JSON.parse(event.currentTarget.responseText);
// The index must be an integer type, else this fails
const penguin = ajaxResponse[index];
penguin.index = index;
penguin.count = ajaxResponse.length;
fn(penguin);
};
oReq.open('GET', 'https://codepen.io/beautifulcoder/pen/vmOOLr.js', true);
oReq.send();
};
}
export class PenguinView {
public element: HTMLElement;
public previousIndex: number;
public nextIndex: number;
public onClickGetPenguin: any;
constructor(element: HTMLElement) {
this.element = element;
this.onClickGetPenguin = null;
}
public render(viewModel) {
this.element.innerHTML = '<h3>' + viewModel.name + '</h3>' +
'<img class="penguin-image" src="' + viewModel.imageUrl +
'" alt="' + viewModel.name + '" />' +
'<p><b>Size:</b> ' + viewModel.size + '</p>' +
'<p><b>Favorite food:</b> ' + viewModel.favoriteFood + '</p>' +
'<a id="previousPenguin" class="previous button" href="javascript:void(0);"' +
' data-penguin-index="' + viewModel.previousIndex + '">Previous</a> ' +
'<a id="nextPenguin" class="next button" href="javascript:void(0);"' +
' data-penguin-index="' + viewModel.nextIndex + '">Next</a>';
this.previousIndex = viewModel.previousIndex;
this.nextIndex = viewModel.nextIndex;
// Wire up click events, and let the controller handle events
const previousPenguin = <HTMLElement>this.element.querySelector('#previousPenguin');
previousPenguin.addEventListener('click', this.onClickGetPenguin);
const nextPenguin = <HTMLElement>this.element.querySelector('#nextPenguin');
nextPenguin.addEventListener('click', this.onClickGetPenguin);
nextPenguin.focus();
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment