Skip to content

Instantly share code, notes, and snippets.

@matthieusieben
Last active February 10, 2017 13:46
Show Gist options
  • Save matthieusieben/b68a2cc83911e16788ce315549ff36b0 to your computer and use it in GitHub Desktop.
Save matthieusieben/b68a2cc83911e16788ce315549ff36b0 to your computer and use it in GitHub Desktop.
Chile component controller reference for angular 1.x
const camelCase = (text) => text
.toLowerCase()
.replace(/-+(.)/g, (_, letter) => letter.toUpperCase())
const getControllerScope = (scope) =>
Object.getPrototypeOf(scope) === Object.getPrototypeOf(scope.$root)
? scope
: scope.$parent
/**
* @ngdoc directive
* @name #
* @param {String} # The name of the property of `$scope.$ctrl` to which attach
* the reference of the component's controller. Defaults to the child
* component's name (camel case).
*
* @description Allows to assign a child component's controller to a property of
* the current compoent's `$ctrl`.
*
* @example
*
* // app.partial.html
* <nav-bar on-home-click="$ctrl.sideBar.toggle()"></nav-bar>
* <side-bar #></side-bar>
*
* // app-bis.partial.html
* <nav-bar on-home-click="$ctrl.customCtrlName.toggle()"></nav-bar>
* <side-bar #="customCtrlName"></side-bar>
*/
octothorpeDirective.$inject = []
function octothorpeDirective () {
return {
priority: -1000, // lower than ng-view (= -400)
restrict: 'A',
scope: false,
link (scope, iElement, iAttr) {
const parentScope = getControllerScope(scope)
const $ctrl = parentScope.$ctrl
const ctrlName = camelCase(iElement[0].nodeName)
const refName = iAttr['#'] || ctrlName
if (!$ctrl) {
throw new Error('Missing parent controller for # directive.')
} else if ($ctrl.hasOwnProperty(refName)) {
throw new Error(`The controller already has property named "${refName}"`)
}
scope.$on('$destroy', () => {
$ctrl[refName] = null
})
// If the element is compiled asynchronously then its controller may need
// several digests before beeing instantiated.
const unwatch = scope.$watch(() => {
const elData = iElement.data()
return elData[`$${ctrlName}Controller`] || elData['$ngControllerController']
}, (elCtrl) => {
if (elCtrl) {
$ctrl[refName] = elCtrl
unwatch()
}
})
}
}
}
export default angular
.module('octothorpe', [])
.directive('#', octothorpeDirective)
.name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment