We want to write a dialog directive in an angularjs application, but have something hard to decide.
Say I have some buttons on the HTML and we want to write a directive 'popup':
<div>
<button popup>Email</button>
<button popup>Phone</button>
<button popup>Other</button>
</div>
When clicked on the button, it will show a popup dialog with something. There are some common UI behaviors between the 3 buttons, as well as some different logic.
We define 3 directives, e.g. popup-email
, popup-phone
, popup-other
:
app.directive('popup-email', ['user', 'ngDialog', function(user, ngDialog) {
return {
link: function(scope, element, attrs) {
if(user.email) {
ngDialog.open({...});
} else {
element.addClass("disabled");
}
}
}
}]);
app.directive('popup-phone', ['user', 'ngDialog', function(user, ngDialog) {
return {
link: function(scope, element, attrs) {
if(user.phone) {
ngDialog.open({...});
} else {
element.addClass("disabled");
}
}
}
}]);
app.directive('popup-other', ['user', 'ngDialog', function(user, ngDialog) {
return {
link: function(scope, element, attrs) {
if(user.other) {
ngDialog.open({...});
} else {
element.addClass("disabled");
}
}
}
}]);
HTML:
<div>
<button popup-email>Email</button>
<button popup-email>Phone</button>
<button popup-email>Other</button>
</div>
In this option, we will define 3 directives, no controller. The good part is each button is a standalone button with the directive, all the logic is inside the directive. The bad part is we have some business logic in each directive, and there are some common logic in all the 3 directives.
We will provide only one directive for the command behavior, and one controller for the difference:
app.directive('popup', ['ngDialog', function(ngDialog) {
return {
link: function(scope, element, attrs) {
if(attrs.enable==="true") {
ngDialog.open({...});
} else {
element.addClass("disabled");
}
}
}
}]);
app.controler('ContactController', function(scope, user) {
scope.enableEmail = if(user.email) true else false;
scope.enablePhone = if(user.phone) true else false;
scope.enableOther = if(user.other) true else false;
});
The HTML will be:
<div>
<button popup enable="{{enableEmail}}">Email</button>
<button popup enable="{{enablePhone}}">Phone</button>
<button popup enable="{{enableOther}}">Other</button>
</div>
For this option, the good part is the directive is reusable, but we will have to define a controller for them.
Second option is wrong, its strange to pass user both to directive and controller. Also if you have it in controller I would pass it to view and determine "enable" attribute there.
But when I speak about passing "user" into directive as dependency. I am not sure if you really want to do that, Id rather pass data to directive using attribute, but i don't know your exact use case, so its up to you.
If you insist on passing user that way I would suggest more clever directive, which accept field on which is enabled.
<button popup="email">Email</button>
When using isolated scope on attribute directive, you can use that attribute also for passing string value with field name, so you can get your field and then determine what to do using
app.directive('popup', function (..) {
...
return {
restrict : "A",
scope : {
field-name : "@popup"
},
link: function(scope, element, attrs) {
...
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments