Reputation: 1203
I have a directive and I'm trying to get the Attrs and pass them to the $scope, but I'm not quite sure how to do that. More specifically I'm trying to set attributes in my template equal to what the name is set in my date-picker tag. I tried setting them as a variable, but obviously that didn't work. Help and further clarification is greatly appreciated. Thanks!
HTML
<date-picker id="dateendPicker" name="date_end"></date-picker>
JS
App.directive('datePicker', function(){
return {
scope: {
name : '@'
},
restrict: 'AE',
replace: 'true',
template: '<div class="date"><div class="input-group"><input type="text" class="form-control" id="{{this_name}}" name="{{this_name}}" ng-model="event.{{this_name}}" required/><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div></div>',
controller: ['$scope', function($scope){
$scope.this_name = this_name;
}],
link: function(scope, element, attrs){
var this_name = attrs.name;
}
}
});
Upvotes: 1
Views: 342
Reputation: 181
There are some issues with your code snippet:
First you do not assign the assign the attrs to the scope
but to a local variable, so it won't be available in the controller function.
You could try this:
App.directive('datePicker', function(){
return {
scope: {
name : '@'
},
restrict: 'AE',
replace: 'true',
template: '<div class="date"><div class="input-group"><input type="text" class="form-control" id="{{this_name}}" name="{{this_name}}" ng-model="event.{{this_name}}" required/><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div></div>',
controller: ['$scope', function($scope){
$scope.this_name = this_name;
}],
link: function(scope, element, attrs){
scope.this_name = attrs.name;
}
}
});
I do not know if this really works since it is not recommended to use controller and link functions at the same time (taken from the directive guide):
Best Practice: use controller when you want to expose an API to other directives. Otherwise use link.
But according to the docs the attrs are also available as $attrs
to the controller function:
App.directive('datePicker', function(){
return {
scope: {
name : '@'
},
restrict: 'AE',
replace: 'true',
template: '<div class="date"><div class="input-group"><input type="text" class="form-control" id="{{this_name}}" name="{{this_name}}" ng-model="event.{{this_name}}" required/><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div></div>',
controller: ['$scope', '$attrs', function($scope, $attrs){
$scope.this_name = $attrs.name;
}]
}
});
But you have already defined name
in the isolate scope, so it should be availble as scope.name
in the conroller or link function:
App.directive('datePicker', function(){
return {
scope: {
name : '@'
},
restrict: 'AE',
replace: 'true',
template: '<div class="date"><div class="input-group"><input type="text" class="form-control" id="{{this_name}}" name="{{this_name}}" ng-model="event.{{this_name}}" required/><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div></div>',
link: function(scope, element, attrs){
console.log(scope.name); // this is your name defined as attribute name="..." on the tag
}
}
});
Upvotes: 0
Reputation: 5864
As I could see from your snippet, you want to use name
attribute as ng-model into directive. I think, you should consider using another type of isolated scope (related SO answer)
Here is my approach (jsFiddle):
app.directive('datePicker', function () {
return {
scope: {
name: '=name'
},
restrict: 'AE',
replace: 'true',
template:
'<div class="date">' +
'<div class="input-group">' +
'<input type="text" ' +
'class="form-control" ' +
'id="bad-idea-to-make-it-editable-id" ' +
'name="{{ name }}" ' +
'ng-model="name" ' +
'required/>' +
'<span class="input-group-addon">' +
'<i class="fa fa-calendar"></i>' +
'</span>' +
'</div>' +
'</div>'
}
});
So now you can edit parent scope from directive. But if you dont want this kind of communication between scopes, use @
scope, as @haimlit has mentioned.
Upvotes: 0
Reputation: 2582
Because of how you've defined your directive scope:
scope: {
name : '@'
}
name is already a variable on your scope. If you're not doing anything special with it on your controller\link functions, you can drop them entirely, and in your template reference it with {{name}}. Just note that if you're creating scope bindings with '@', then in your html you should pass your data as an angular expression, meaning:
name="{{date_end}}"
Upvotes: 2