I'm building a form builder AngularJS app, and I have the following AngularJS directive representing the UI to edit a TextField:
angular.module('myApp.directives').directive('textFormFieldElement', ['$timeout', function($timeout) {
'use strict';
return {
restrict: 'A',
scope: {
element: '='
},
template: '<div class="form-element text-form-field">' +
' <span class="identifier">TF</span>' +
' <strong class="heading" ng-bind="headingText()"></strong>' +
' <div class="editor">' +
' <div class="form-group">' +
' <label>Enter the field name:</label>' +
' <input ng-model="element.fieldName" type="text" class="form-control" />' +
' </div>' +
' <div class="form-group">' +
' <label>Enter a label for the field:</label>' +
' <input ng-model="element.label" type="text" class="form-control" />' +
' </div>' +
' <div class="form-group">' +
' <label>Enter a note for the field:</label>' +
' <input ng-model="element.note" type="text" class="form-control" />' +
' </div>' +
' <div class="checkbox">' +
' <label>' +
' <input ng-model="element.required" type="checkbox" /> Required' +
' </label>' +
' </div>' +
' </div>' +
'</div>',
link: function(scope, element, attributes) {
scope.element.fieldName = scope.element.fieldName || 'TextField';
// Expand the editor when creating new elements, and focus on the first field once rendered.
if (!scope.element._id) {
$timeout(function() {
element.find('.editor').addClass('expanded');
element.find('.editor').find('input:first').select();
}, 10);
}
scope.headingText = function() {
if (scope.element.fieldName.length && scope.element.fieldName.length > 0) {
return scope.element.fieldName;
}
return 'TextField';
};
}
};
}]);
I also have other controls, like a PhoneField, an EmailField, and a RadioButtonListField.
These directives will often have common HTML in their templates as well as common JavaScript behavior. I'd like a way to share this across directives, without polluting the global namespace.
What are some ways this can be achieved?
require(). As for sharing common JavaScript functionality, I would suggest looking at using services. I would be careful to not name the services too generally and cram too much into one service. I would also be careful about sharing data between services, as services are only initialized once per app load.