Reputation: 4440
I am trying to create three different directives that need to communicate together, and this isn't really a problem but I would like to explore the possibility of using an isolate scope, or at least as small a scope as possible between them.
Because sharing directly on the controller scope is so discouraged, I enacted this to try and get around that. The only solution I've seen immediately is to make all three behaviors in the same single directive, so that they all use the same scope - but this is very messy.
This is an extremely slim example of how it works. The full code is very long and it's not useful without a lot of extra context. I'm trying to trim it down to just what I need help with.
scope
properties between the directives?angular.module('app', [])
.directive('dataSourceUrl', ['$parse', function($parse) {
return {
restrict: 'A',
priority: 10,
link: function(scope, element, attributes) {
var path = attributes.dataSourceUrl;
angular.extend(scope.options, {
/* more code */
});
}
}
}])
.directive('dataSourceOptions',
['$parse', function($parse) {
return {
restrict: 'A',
priority: 9,
link: function(scope, element, attributes) {
var options = scope.$eval(attributes['dataSourceOptions']);
angular.extend(scope.options, {
/* more code */
});
}
}
}])
.directive('dataSourceColumns',
['$parse', function($parse) {
return {
restrict: 'A',
priority: 9,
link: function(scope, element, attributes) {
var columns = scope.$eval(attributes.dataSourceColumns);
angular.forEach(columns, function(value, key) {
switch(value) {
case "Id":
scope.options.columns.push({ field: "Id" /* more code */ });
break;
case "Name":
scope.options.columns.push({ field: "Name" /* more code */ });
break;
/* more code */
}
});
}
}
}]);
My experience with angular is minimal, I am very new. I have researched isolate scope extensively, but it is proving to be more difficult than I thought. My goal is to use these directives kind of like this ...
<div kendo-grid data-source-url="'path/to/data'"
data-source-options="options"
data-source-columns="['Id','Name','Abbreviation','Group']">
</div>
Upvotes: 1
Views: 624
Reputation: 18055
you can have multiple isolate scoped directive on same element. though as far as i remember, read it somewhere, that multiple isolate scoped directive do share the scopes.
you can read more about scopes here
regarding sharing the data between directives, are the directives independent or are they in parent-child relationship?
if parent child then use require
property of directives. and pass data only to parent directive and access it in child directive.
if they are sibling or independent, pass data to each directive separately.
lets assume that dataSourceUrl
display changes on basis of parameters in dataSourceOptions
. then you can use require property.
.directive('dataSourceUrl',
['$parse', function($parse) {
return {
restrict: 'A',
require: 'dataSourceOptions'
link: function(scope, iElement, iAttrs, ctrlOptions)
{
//ctrlOption.showHeadeers or something
}
Upvotes: 2
Reputation: 3934
Here is the fiddle where two directive are integrated
http://jsfiddle.net/Wijmo/MTKp7/
and code is
angular.module("btst", []).
directive("btstAccordion", function () {
return {
restrict: "E",
transclude: true,
replace: true,
scope: {},
template:
"<div class='accordion' ng-transclude></div>",
link: function (scope, element, attrs) {
// give this element a unique id
var id = element.attr("id");
if (!id) {
id = "btst-acc" + scope.$id;
element.attr("id", id);
}
// set data-parent on accordion-toggle elements
var arr = element.find(".accordion-toggle");
for (var i = 0; i < arr.length; i++) {
$(arr[i]).attr("data-parent", "#" + id);
$(arr[i]).attr("href", "#" + id + "collapse" + i);
}
arr = element.find(".accordion-body");
$(arr[0]).addClass("in"); // expand first pane
for (var i = 0; i < arr.length; i++) {
$(arr[i]).attr("id", id + "collapse" + i);
}
},
controller: function () {}
};
}).
directive('btstPane', function () {
return {
require: "^btstAccordion",
restrict: "E",
transclude: true,
replace: true,
scope: {
title: "@",
category: "=",
order: "="
},
template:
"<div class='accordion-group' >" +
" <div class='accordion-heading'>" +
" <a class='accordion-toggle' data-toggle='collapse'> {{category.name}} - </a>" +
" </div>" +
"<div class='accordion-body collapse'>" +
" <div class='accordion-inner' ng-transclude></div>" +
" </div>" +
"</div>",
link: function (scope, element, attrs) {
scope.$watch("title", function () {
// NOTE: this requires jQuery (jQLite won't do html)
var hdr = element.find(".accordion-toggle");
hdr.html(scope.title);
});
}
};
})
and also you can see the accordion example from this js
https://github.com/angular-ui/bootstrap/blob/master/src/accordion/accordion.js
Upvotes: 1