Skip to content

Instantly share code, notes, and snippets.

@Super-Chama
Created March 3, 2023 04:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Super-Chama/987d9a78e6bba05ca8aeb3e5e740590e to your computer and use it in GitHub Desktop.
Save Super-Chama/987d9a78e6bba05ca8aeb3e5e740590e to your computer and use it in GitHub Desktop.
Basic Vuex (Flux) pattern for Angular.js (1x)
(function () {
"use strict";
angular.module("app").controller("CounterController", CounterController);
CounterController.$inject = ["$scope", "storeService"];
function CounterController($scope, storeService) {
var vm = this;
vm.counter = storeService.$state.counter;
vm.incrementCounter = incrementCounter;
vm.decrementCounter = decrementCounter;
function incrementCounter() {
storeService.dispatch("adjustCounter", "increment");
}
function decrementCounter() {
storeService.dispatch("adjustCounter", "decrement");
}
var subscriber = storeService.subscribe((mutation, state) => {
if (
mutation.type === "INCREMENT_COUNT" ||
mutation.type === "DECREMENT_COUNT"
) {
vm.counter = state.counter;
}
});
$scope.$on("$destroy", function () {
subscriber(); //unsub
});
}
})();
// Skeleton implementation of vuex
var createStore = (function () {
/**
* Store contains state, mutations, actions
*/
function createStore(
{ state, actions, mutations } = {
state: {},
actions: {},
mutations: {},
}
) {
var $state = {};
var $subscribers = [];
var _initialState = JSON.parse(JSON.stringify(state));
$state = Object.assign({}, _initialState);
console.log("[store] store initialized:", $state);
// commits are synchronous and returns nothing
function commit(...params) {
const [type, payload] = params;
console.log("[store] commit: " + type, payload);
if (typeof mutations[type] === "function") {
mutations[type]($state, payload);
for (const key in $subscribers) {
$subscribers[key](
{ type, payload },
Object.assign({}, $state)
);
}
} else {
console.warn(`[store] Invalid mutation type: ${type}.`);
}
}
// actions can be async may return promise
function dispatch(...params) {
const [type, payload] = params;
console.log("[store] dispatch: " + type, payload);
if (typeof actions[type] === "function") {
return actions[type](
{
commit: commit,
state: Object.assign({}, $state),
},
payload
);
} else {
console.warn(`[store] Invalid action: ${type}.`);
}
}
function restore() {
$state = Object.assign({}, _initialState);
}
function subscribe(handler) {
if (typeof handler === "function") {
if ($subscribers.indexOf(handler) === -1) {
$subscribers.push(handler);
console.log(`[store] Add subscriber`);
return () => {
const i = $subscribers.indexOf(handler);
if (i > -1) $subscribers.splice(i, 1);
console.log(`[store] Remove subscriber`);
};
}
} else {
console.warn(`[store] Invalid subscriber`);
}
}
return {
$state,
commit,
dispatch,
restore,
subscribe,
};
}
return createStore;
})();
(function () {
"use strict";
angular.module("app").service("storeService", storeService);
storeService.$inject = [];
function storeService() {
var store = createStore({
state: {
counter: 0,
},
mutations: {
INCREMENT_COUNT(state) {
state.counter++;
},
DECREMENT_COUNT(state) {
state.counter--;
},
},
actions: {
adjustCounter(context, payload) {
if (payload === "increment") {
context.commit('INCREMENT_COUNT');
}
if (payload === "decrement") {
context.commit('DECREMENT_COUNT');
}
},
},
});
return store;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment