I've been recently digging into Angularjs, as I'm trying to make some customization, and this is what I figured out after a reading loads of blog posts covering the subject. I'm not an angular expert so I don't know how this affects performance.
The following script is from an extension using hook_civicrm_angularModules and Angular's $provide
service in conjunction with the decorator
function to intercept a CiviCRM directive and 'decorate' it to add/replace/extend behaviour, more info here.
Demonstration:
// myModule.js
(function(angular, $, _) {
// declare your module
angular.module('myModule', []);
// Hook into crmMailing module
angular.module('crmMailing').config(function($provide){
// intercept crmMailingBlockMailing directive, note the 'Directive' suffix
$provide.decorator('crmMailingBlockMailingDirective', function($delegate){
var directive = $delegate[0];
// Original compile function
var compile = directive.compile;
// New compile function
directive.compile = function(Element, Attrs){
var link = compile.apply(this, arguments);
// Append your custom directive
Element.append('<div crm-my-directive></div>');
return function(scope, elem, attrs){
link.apply(this, arguments);
};
};
return $delegate;
});
});
/*
* Extending crmMailing
*/
// Your simple custom directive
angular.module('crmMailing').directive('crmMyDirective', function(){
return {templateUrl: CRM.resourceUrls['uk.co.myextension'] + '/ang/directives/crmMyDirective.html',
controller: 'ExampleCtrl',
};
});
// Your controller
angular.module('crmMailing').controller('ExampleCtrl', function($scope, crmMsgTemplates){
$scope.$watchCollection('mailing', function(mailing){
crmMsgTemplates.get(mailing.msg_template_id)
.then(function(value){
mailing.msg_template_title = value.msg_title;
});
});
});
})(angular, CRM.$, CRM._);
Custom directive template
<div id="my-directive">
<div crm-ui-accordion="{title: ts('My Custom Directive')}">
<p>Template Id: {{mailing.msg_template_id}} | Template Title: {{mailing.msg_template_title}}</p>
</div>
</div>
You can pretty much create your own services/factories, directives, etc or change the behavior of existing ones and hook it into the Mailing app.
Hope it helps.
var scope = angular.element('[ng-controller="MsgTemplateCtrl"]').scope(); scope.$watch('mailing.msg_template_id', function(){ console.log(scope.mailing.msg_template_id); });
with scope.mailing you can access and listen to the mailing params, I guess you already know it but if you enable debug and add?angularDebug
at the end of the url you will see a new accordion with the params, hope that helps somehowsetTimeout()
it does work as expected, the mailing page always takes a 2-4 seconds to completely load all the elements in my case