Skip to content

Instantly share code, notes, and snippets.

@soundanalogous
Last active December 20, 2015 23:18
Show Gist options
  • Save soundanalogous/6211011 to your computer and use it in GitHub Desktop.
Save soundanalogous/6211011 to your computer and use it in GitHub Desktop.
// treat the scope as read-only in views
// treat the scope as write-only in controllers
/**
* use attrs to read from scope
*/
<div my-attribute="propName">
app.directive('myDirective', function () {
return {
link: function (scope, elem, attrs) {
// read from the scope
scope.$watch(attrs.myAttribute, function (name) {
// do something with name
});
}
}
});
/**
* use $parse to write to scope
*/
app.directive('myDirective', function ($parse) {
return {
link: function (scope, elem, attrs) {
// write to the scope (does not work with isolate scope)
$parse(attrs.myAttribute).assign(scope, 'abc');
}
}
});
/**
* write to scope from directive using isolate scope
*/
app.directive('myDirective', function ($timeout) {
return {
scope {
myAttribute: '=' // isolage
}
link: function (scope, elem, attrs) {
// this is totally stupid but necessary if you need to change the value quickly
// it will call $apply safely. If you try to call $apply directly and need to call
// it sevaral times you'll get a "$digest already in progress error" since angular
// using $timeout somehow dodges this issue
$timeout(function () {
scope.myAttribute = "newValue";
})
}
}
});
/*************************************************************************************************/
/**
* pass callback to directive
*/
// pass callback function
// would you even need the parameter or could you just pass someCtrlFn?
<div my-dir ctrl-fn="someCtrlFn(arg1)"></div>
app.controller('MainCtrl', function($scope) {
$scope.someCtrlFn = function (arg1) {
};
})
// for a directive using an isolate scope
app.directive('myDirective', function () {
return {
scope: { ctrlFn: '&' },
link: function (scope, elem, attrs) {
...
scope.ctrlFn({arg1: someValue});
}
}
});
// for a directive not using isolate scope
app.directive('myDirective', function ($parse) {
return {
scope: true, // or no scope
link: function (scope, elem, attrs) {
var invoker = $parse(attrs.ctrlFn);
...
invoker( {arg1: someValue} );
}
}
});
/*************************************************************************************************/
/**
* emit event from directive
*/
app.controller('MainCtrl', function ($scope) {
// if you had many directives firing this event you'd need an identifier
// passed in the event data
$scope.$on('eventName', function (evt, arg) {
});
});
app.directive('myDirective', function () {
return {
link: function (scope, elem, attrs) {
// Not sure how (or if) isolate scope affects this
// If there are multiple instances of this directive I assume you'd
// also want to pass some sort of an ID as well (unless you get)
// that automatically through the event parameter.
scope.$emit('eventName', { key: "value" });
}
}
});
/*************************************************************************************************/
/**
* Calling a method on a directive "instance" in response to a UI event
*/
<button ng-click="doSomething()">A Button</button>
<div my-directive some-attr="prop"></div>
app.controller('MainCtrl', function () {
// hacky but the only thing that seems to work
$scope.doSomething = function () {
// toggle a property value to trigger a change which will subsequently call
// a method on the directive. This will also get called on the correct directive
// if it is a single instance as long as 'doSomething' is unique to the instance
// or is passed a value to resolve the correct instance
$scope.prop = !$scope.prop;
}
});
app.directive('MyDirective', funciton () {
return {
scope: {
someAttr: '=' // isolate
}
link: function (scope, elem, attrs) {
var someFunc = funciton () {
};
scope.$watch('someAttr', funciton (newVal, oldVal) {
if (newVal !== undefined) {
someFunc();
}
});
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment