Creating Angular.js directives containing other directives

I am trying to come up with a library for reusing directives. The first two directives I tried to implement are DatePicker and DateRangePicker. DateRangePicker must contain two DatePickers.

I want DatePicker to have a signature similar to:

<div cx-date-picker="" cx-label="myLabel" cx-id="myDate" cx-source="myDateVarInScope"></div> 

and I want the DateRangePicker to look like this:

 <div cx-date-range-picker cx-id="searchRangePicker" cx-source="myDateRangeInScope"></div> 

where myDateRangeInScope contains the elements: startDate and endDate

I have looked at several examples of creating directives, but I cannot figure out how to pass parameters to the main directives. Here is the code for DatePicker

 angular.module('ng').directive('cxDatePicker', function () { return { restrict: 'A', scope: 'isolate', template: '<div class="control-group input-append">' + '<label for="{{theId}}" class="label">{{theLabel}}</label>' + '<input id="{{theId}}" class="input-small" type="text" ' + 'ng-model="theSource" data-date-format="dd/mm/yyyy" bs-datepicker>' + '<button type="button" class="btn" data-toggle="datepicker">' + '<i class="icon-calendar"></i></button>' + '</div>', link: function (scope, iterStartElement, attr) { var theId = attr['cxId']; scope.theLabel = attr['cxLabel'] scope.theId = attr['cxId']; scope.theSource = attr['cxSource']; } }; }); 

which displays the correct values โ€‹โ€‹for Id and theLabel but does not display the correct date.

And this is the code for DateRangePicker that cannot set attributes for the underlying DatePickers.

 angular.module('ng').directive('cxDateRangePicker', function () { return { restrict: 'A', scope: 'isolate', template: '<div cx-date-picker="" cx-source="{{startSource}}" ' + 'cx-label="{{fromLabel}}" cx-id="{{startId}}"></div>' + '<div cx-date-picker="" cx-source="{{endSource}}" cx-label="{{toLabel}}" ' + ' cx-id="{{endId}}"></div>', link: function (scope, iterStartElement, attr) { var theId = attr['cxId']; scope.startId = theId + "From"; scope.endId = theId + "To"; scope.fromLabel = "From"; scope.toLabel = "To"; scope.startSource = attr['cxSource'] + ".startDate"; scope.endSource = attr['cxSource'] + ".endDate"; } }; }); 

Can someone point me to a solution? I saw that the link () methods of the underlying DatePickers are called before the link () method of DateRangePicker. Therefore, it is not surprising that values โ€‹โ€‹are not transmitted. But I lack a common conceptual understanding to solve the problem. The official docs didn't help much.

In general, has anyone tried to achieve a similar goal - to create directives on top of other directives and, by doing this, to create a library of components for the business domain?

+4
source share
2 answers

The point is the correct use of the area. The @ attribute simply copies the values โ€‹โ€‹from the tag attributes statically, instead you should use the = attribute, which binds the variables of the parent scope to the scope of the directive. I created this plunker to show you how to implement both directives correctly.

+3
source

Focus on processing. This means that Angular.js really has an audio component architecture that allows you to create larger components on top of smaller ones. This is a good advance over Backbone. I am wondering if Ember.js has similar features.

 angular.module('ng').directive('cxDatePicker', function () { return { restrict: 'A', scope: { cxLabel: '@', cxId: '@', cxSource: '=' }, template: '<div class="control-group input-append">' + '<label for="{{cxId}}" class="label" style="margin-right: 6px;">{{cxLabel}}</label>' + '<input id="{{cxId}}" class="input-small" type="text" ng-model="cxSource" data-date-format="dd/mm/yyyy" bs-datepicker>' + '<button type="button" class="btn" data-toggle="datepicker"><i class="icon-calendar"></i></button>' + '</div>', link: function (scope, iterStartElement, attr) {} }; }); angular.module('ng').directive('cxDateRangePicker', function () { return { restrict: 'A', scope: { cxId: '@', cxSource: '=' }, template: '<div cx-date-picker="" cx-source="cxSource.startDate" cx-label="From" cx-id="{{cxId}}From" ></div>' + '<div cx-date-picker="" cx-source="cxSource.endDate" cx-label="To" cx-id="{{cxId}}To" ></div>', link: function (scope, iterStartElement, attr) {} }; }); 
0
source

Source: https://habr.com/ru/post/1483910/


All Articles