I am creating a big Angular.JS application which uses some third party modules like ui-select and ui-bootstrap. To avoid repeating myself I started to create directives which are wrapping for example ui-select code and the logic to retrieve / search for data.
Goal: The goal was to create a directive which can be used in the template like that, without duplicating code in controllers:
<tq-car-select ng-model="model.car"></tq-car-select>
What I try to avoid:
<select ng-options="car.id as car.name for car in cars"></select>
and duplicate following code in all controllers which are using the select:
$scope.cars = carResource.query();
$scope.$watch('model'), function (newValue, oldValue) {
$scope.cars = carResource.query({model: $scope.model});
});
I created directives for that kind of select fields.
Actual Example with ui-select:
tq-lead-select.html:
<ui-select ng-model="$parent.tqModel" style="display: block">
<ui-select-match placeholder="tippen ...">{{$select.selected.bezeichnung}}</ui-select-match>
<ui-select-choices repeat="lead in leads | filter:{bezeichnung: $select.search}">
<div ng-bind-html="lead.bezeichnung | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
tqLeadSelect.ts (TypeScript):
export function tqLeadSelect(tqLeadSelects): ng.IDirective {
var dir: ng.IDirective = {};
dir.scope = {
tqModel: '=',
tqCompany: '='
};
dir.restrict = 'E';
dir.templateUrl = '/js/templates/leadApp/tq-lead-select.html';
dir.replace = false;
dir.controller = function ($scope: any) {
if (tqLeadSelects != null && $scope.tqCompany != null) {
$scope.leads = tqLeadSelects.getLeadsFromFirma({ id: $scope.tqCompany });
}
$scope.$watch('tqCompany', (newValue, oldValue) => {
if (newValue === oldValue) return;
$scope.leads = tqLeadSelects.getLeadsFromFirma({ id: $scope.tqCompany });
}, true);
}
return dir;
}
tqLeadSelect.$inject = ['tqLeadSelects'];
Problems:
- I need isolated scope, because some views use multiple instances of one field.
- I am using the isolated scope variable tqModel which is set by the ngModel of the ui-select directive
- I would like to use ng-required without creating a tq-required scope variable on tqLeadSelect directive
Questions:
- Am I doing it right? Are there better ways achieving my goals?
- how are you defining select fields with supporting controller code for retrieving data and additional functions?