Edit
How to set for this <input ng-model="this['newPlayer']['personal_info']['first_name']">
the ['newPlayer']['personal_info']['first_name'] dynamically from variable?
Something like this: <input ng-model="this[variable]">
You don't have to get it from the attributes just add this to your directive require: 'ngModel'
like this
app.directive("textInput", () => {
return {
templateUrl: "/text-input.html",
require: 'ngModel'
scope: true,
link: function($scope, $element, $attrs, ngModel) {
angular.element($element).append($scope[$attrs.myModel]);
}
}
});
and you have your different ngModel for each textInput instance in link function
Related
I am very new to Angular. I am trying to read/pass some data to my angular directive from the template.
<div class="col-md-6" approver-picker="partner.approverPlan.data" data-pickerType="PLAN"></div>
I have this in my angular template and I have this in different places. So I want to know in my Angular code, which picker is being clicked.
I am thinking to read the data-pickerType value in my directive.(I am able to read this in jQuery but do not know how to in Angular)
This is my directive code.
Partner.Editor.App.directive('approverPicker', [
'$compile', function ($compile) {
return {
scope: {
"approvers": "=approverPicker"
},
templateUrl: '/template/assets/directive/ApproverPicker.html',
restrict: 'EA',
link: function ($scope, element) {
...........
}
};
}
]);
How can I read the data-pickerType value in the directive or is there a better way of doing this?
The data attributes can be accessed in Angular directive by passing attrs variable in the link function.
Partner.Editor.App.directive('approverPicker', [
'$compile', function ($compile) {
return {
scope: {
"approvers": "=approverPicker"
},
templateUrl: '/template/assets/directive/ApproverPicker.html',
restrict: 'EA',
link: function ($scope, element, attrs) { //passing attrs variable to the function
//accessing the data values
console.log(attrs.pickertype);
//you can access any html attribute value for the element
console.log(attrs.class);
}
};
}
]);
I'm trying to pass a boolean value from my controller into my isolated scope directive. When I console.log(attrs) from the directive's link function, the someBoolean attribute is a string, rendering the actual text "main.bool" instead of a true or false value. When I toggle the boolean value from the outer controller, I want it to be updated in the directive.
https://plnkr.co/edit/80cvLKhFvljnFL6g7fg9?p=preview
app.directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
scope: {
someBoolean: '='
},
templateUrl: 'myDirective.html',
link: function(scope, element, attrs) {
console.log(scope);
console.log(attrs);
},
controller: function($scope, $element, $attrs) {
console.log(this);
},
controllerAs: 'directiveCtrl',
bindToController: true
};
});
Controller
app.controller('MainCtrl', function($scope) {
var vm = this;
vm.bool = true;
vm.change = function() {
vm.bool = !vm.bool;
}
});
The template
<div>
Inside directive: {{someBoolean}}
</div>
As you have attached your directive Controller to directiveCtrl instead of mainCtrl, you'll access the variable someBoolean using directiveCtrl.someBoolean.
In this case, change the HTML to:
<div>
Inside directive: {{directiveCtrl.someBoolean}}
</div>
Plunker.
Another solution would be to remove the bindToController property inside your directive. With this, you don't need to use the controller name before the variable. Working Plunker.
Read more about this bindToController feature here.
I am writing a directive in AngularJs and I want to pass ng-model as an argument.
<div class="col-md-7"><time-picker></time-picker></div>
The directive is:
app.directive('timePicker', function () {
return {
restrict: 'E',
replace: true,
template: '<input type="text" class="form-control time-picker" ng-model="emp.signin">',
link: function ($scope, element, form) {
$(element).timepicker({'timeFormat': 'H:i:s'});
}
}
})
It is working fine, and here the ng-model is emp.signin. I want to be able to pass this ng-model dynamically as argument
How is this possible?
You can use
<div class="col-md-7"><time-picker model-value="emp.signin"></time-picker></div>
Angular
app.directive('timePicker', function () {
return {
restrict: 'E',
replace: true,
template: '<input type="text" class="form-control time-picker"ng-model="modelValue ">',
scope: {
modelValue : '=',
}
link: function ($scope, element, form) {
$(element).timepicker({'timeFormat': 'H:i:s'});
}
}
})
Explaination
The “=” prefix will create a two-way binding between the parent and
directive scope and it’ll always expect the attribute value to be the
model name which means you cannot provide an expression as the value
of attribute mapped to “=” prefix.
For reference: "http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/"
I am having trouble getting a click event in a directive with an isolated scope to work using "controller as" syntax in Angular 1.3 the code for the directive is as follows:
myDirectives.directive('gsphotosquare', dirfxn);
function dirfxn() {
var directive = {
replace: false,
scope: {
photoInfo: '=',
photoBatchNum: '=',
thumbnailwidth: '='
},
restrict: 'EA',
controller: Ctrller,
controllerAs: 'ctrl',
template: '<div ng-click="ctrl.squareClicked()">test</div>',
//templateUrl: 'views/directives/gsphotosquare.html',
bindToController: true, // because the scope is isolated
link: linkFunc //adding this didn't help
};
return directive;
}
function Ctrller() {
var vm = this;
vm.squareClicked = function () {
alert('inside clickhandler for gsphotosquare directive');
};
}
function linkFunc(scope, el, attr, ctrl) {
el.bind('click', function () {
alert('inside clickhandler for gsphotosquare directive');
});
}
And here is how the directive is used in the DOM:
<span class="input-label">General Site Photos</span>
<div class=" item row">
<gsphotosquare photo-info="mt.photos.v1f1[0]" photo-batch-num="mt.photoBatchNum" ></gsphotosquare>
<gsphotosquare photo-info="mt.photos.v1f1[1]" photo-batch-num="mt.photoBatchNum" ></gsphotosquare>
<gsphotosquare photo-info="mt.photos.v1f1[2]" photo-batch-num="mt.photoBatchNum" ></gsphotosquare>
<gsphotosquare photo-info="mt.photos.v1f1[3]" photo-batch-num="mt.photoBatchNum" ></gsphotosquare>
</div>
Any ideas why clicking on the rendered directive doesn't show the alert?
Try defining your controller a little differently:
myDirectives.controller('Ctrller', Ctrller);
then in your directive:
controller: 'Ctrller as ctrl',
With HTML like this...
<div ng-app="myApp">
<div ng-controller="inControl">
I like to drink {{drink}}<br>
<input my-dir ng-model="drink"></input>
</div>
</div>
and javascript like this...
var app = angular.module('myApp', []);
app.controller('inControl', function($scope) {
$scope.drink = 'water';
});
app.directive('myDir', function(){
return {
restrict: 'A',
link: function($scope, element, attrs, ctrl) {
// why is this logging undefined?
console.log(ctrl);
}
};
});
Why can I not access the controller from within my directive? Why is my call to ctrl giving me undefined?
EDIT: add demo...
Fiddle available here: http://jsfiddle.net/billymoon/VE9dX/
see multiple controller can be attached with one app and simillarly multiple directive can be attached with one app, so if you wants to use one controller in one directive than you can set the controller property of directive to the name of the controller you wants yo attach with like in your case
app.directive('myDir', function(){
return {
restrict: 'A',
controller: 'inControl'
link: function($scope, element, attrs, ctrl) {
// why is this logging undefined?
console.log(ctrl);
}
};
});
Despite this working with require:ngModel, this still isn't the best approach as it ties the directive directly to the controller. If you want your directive to communicate with your controller, you could be setting and reading off the scope.
HTML:
<div ng-app="myApp">
<div ng-controller="inControl">
I like to drink {{drink}}<br />
<input my-dir="drink"></input>
</div>
</div>
JS:
var app = angular.module('myApp', []);
app.controller('inControl', function($scope) {
$scope.drink = 'asdfasdf';
});
app.directive('myDir', function(){
return {
restrict: 'A',
link: function(scope, element, attrs) {
console.log(scope[attrs.myDir]);
}
};
});
Alternatively you can use my-dir="{{drink}}" and read it as attrs.myDir.
http://jsfiddle.net/8UL6N/1/
Adding require: 'ngModel', fixed it for me - not sure if there is another way to specify it...
app.directive('myDir', function(){
return {
restrict: 'A',
require: 'ngModel',
link: function($scope, element, attrs, ctrl) {
// why is this logging undefined?
console.log(ctrl);
}
};
});