I have the following directive:
app.directive('skiTest', function($timeout,$compile) {
return {
'replace': true,
'restrict': 'E',
'scope': {
'data': '=',
'selecto': '#',
'ngModel': '='
},
link: function (scope, element, attrs) {
attrs.$observe("selecto", function () {
$timeout(function () { // we need a timeout to compile after the dust has settled
$compile(element.contents())(scope); //recompile the HTML, make the updated content work.
},0);
});
},
'template':'<div><select name="testSelect" ng-model="ngModel" ng-options="{{selecto}} in data"><option value="">Code</option></select></div>'
}
});
http://jsfiddle.net/L269zgbd/1/
If i'll try to select a country in the directive selection box, the ng-model object is being set to null.
Any idea why is that and how can i solve this problem?
Basically i want the same behavior on the directive selection as the one i get with the non directive selection.
Thanks!
If you upgrade the version of angular used in the fiddle the following works without using $compile or $timeout
app.directive('skiTest', function () {
return {
'replace': true,
'restrict': 'E',
'scope': {
'data': '=',
'selecto': '#',
'ngModel': '='
},
'template': '<div><select name="testSelect" ng-model="ngModel" ng-options="{{selecto}} in data"><option value="">Code</option></select></div>'
}
});
DEMO
If you can't upgrade your version of angular like charlietfl suggests you can use the $compile function instead:
app.directive('skiTest', function($timeout,$compile) {
return {
'replace': true,
'restrict': 'E',
'scope': {
'data': '=',
'selecto': '#',
'ngModel': '='
},
'template':'<div><select name="testSelect" ng-model="ngModel" ng-options="{{selecto}} in data" ng-change="changed()"><option value="">Code</option></select></div>',
compile: function(tElement, tAttributes){
tElement[0].innerHTML = tElement[0].innerHTML.replace('{{selecto}}', tAttributes.selecto);
}
}});
jsfiddle: http://jsfiddle.net/r366r3b7/
Related
I had a directive,
.directive('lbd', function () {
return {
restrict: 'E',
scope: {
context: '=',
dui: '='
},
templateUrl: 'app/templates/lbd-directive.html',
});
Sometimes I call this without any atttrs but I am not sure how to do that.
This is not working,
<lbd class="col-xs-12 lbd" context="" dui="" ></lbd>
Can anyone please help me.Thanks.
Try in this way
.directive('lbd', function () {
return {
restrict: 'E',
scope: {
context: '=?', // notice the ? makes this parameter optional.
dui: '=?' // notice the ? makes this parameter optional.
},
templateUrl: 'app/templates/lbd-directive.html',
});
Your directive is correct. It's only missing unclosed bracket which should throw an error in the log. code should be
.directive('lbd', function () {
return {
restrict: 'E',
scope: {
context: '=',
dui: '='
},
templateUrl: 'app/templates/lbd-directive.html'
}
});
you could see the running code here
I created a custom directive in angular. I would like to pass parent data through the directive using scope but I'm getting 'undefined' when I log scope and scope.questionId.
HTML
<a class="waves-effect waves-light btn" my-directive="" on-flag="someFunction" question-id="question">Flag</a>
Angular Directive
angular.module('myApp').directive('myDirective', function($http) {
return {
restrict: 'A',
scope: {
onFlag: '&onFlag',
questionId: '='
},
link: function(scope, element, attrs) {
element.click(function() {
console.log(scope);
console.log(scope.questionId);
return;
});
}
};
});
Try this
elem.bind:- It uses the JQLite which is lite version of JQuery. Here we are writing the code to handle the click event performed on the directive.
It is same like JQuery $("class or id").click(). (I hope this explains is sufficient)
angular.module('myApp').directive('myDirective', function($http) {
return {
restrict: 'A',
scope: {
onFlag: '&onFlag',
questionId: '='
},
link: function(scope, elem, attrs) {
elem.bind('click', function() {
console.log(scope.questionId);
});
}
};
});
I have no idea why, but:
#myApp.directive 'myDirective', () ->
return {
restrict: 'E',
scope: {
source: '='
},
link: (scope, element, attrs) ->
console.log scope.source
}
<my-directive source="foobar"></my-directive>
returns undefined. The thing which confuses me is that in my other directive, print-user, everything works fine.
return {
restrict: 'E',
scope: {
user: '=',
showName: '=',
showAvatar: '=',
avatarSize: '='
},
templateUrl: 'templates/partials/print-user.html',
link: (scope, element, attrs) ->
scope.tooltip = scope.user.username
}
Here I'm able to get the user object within the template by {{user}}.
Within myDirective I could get the source attribute by attrs.source - but why is it working within my user directive?
EDIT / Solution
Thanks to Aleksandar Bencun: using <my-directive source="'foobar'"></my-directive> (additional single quotes) solved the problem.
I want to get a value straight from an attribute directive:
<form cronos-dataset="People as p">
Form Content
</form>
In my JS I tried:
app.directive('cronosDataset',[function() {
return {
restrict: 'A',
controller: 'CronosGenericDatasetController',
scope: {
"cronos-dataset" : '#'
}
};
}])
.controller("CronosGenericDatasetController",['$scope', function($scope) {
alert($scope["cronos-dataset"]);
}]);
I want to alert "People as p" string but I get undefined. Is that right path or should I go thorough a different approach?
You are supposed to have camelCase in the scope declaration
app.directive('cronosDataset',[function() {
return {
restrict: 'A',
controller: 'CronosGenericDatasetController',
scope: {
cronosDataset : '#'
}
};
}])
Here is a demo to see different variations
http://plnkr.co/edit/G6BiGgs4pzNqLW2sSMt7?p=preview
Make a link function instead:
app.directive('cronosDataset',[function() {
return {
scope: {},
restrict: 'A',
link: function (scope, elem, attrs) {
alert(attrs.cronosDataset);
}
I want to nest two directives and the inner directive has a ng-class bound to a function that takes a scope attribute from inner and outer scopes and return a Boolean
This is the HTML:
<ul my-toolbar disabled-when="myCtrl.isProcessing" >
<li my-action-button action="myCtrl.action()" disable-when="myCtrl.isSad()" />
</ul>
This is my outer directive:
myApp.directive("myToolbar", function() {
return {
restrict: 'A',
scope: {
disabled: '=disabledWhen'
},
transclude: true,
controller: function($scope) {
this.isDisabled = function() {
return $scope.disabled;
}
}
};
});
And this is my inner directive:
myApp.directive("myActionButton", function() {
return {
restrict: 'A',
scope: {
action: '&',
disabled: '=disabledWhen'
},
replace: true,
template: "<li ng-class='{disabled: isDisabled()}'><a ng-click='isDisabled() || action()' /></li>",
link: function(scope, elem, attrs, toolbarCtrl) {
scope.isDisabled = function() {
return toolbarCtrl.isDisabled() || scope.disabled;
};
}
};
});
Now the problem is that the ng-class='{disabled: isDisabled()}' binding is initialized once in the beginning but not updated when myCtrl.isProcessing changes!
Can someone please explain why? and how can I fix this without changing my design?
#Jonathan as requested I put my angular code in a fiddle and (this is part that's irritating me now) it works!
http://jsfiddle.net/shantanusinghal/ST3kH/1/
Now, I'll go back to seeing why it doesn't work for me in my production code!! *puzzled