directive not showing scope in template - angularjs

something simple im sure..
ive set up a very simple directive that accepts an isolated scope item
the template simply prints out the name.
.directive('createDirective', function () {
return {
restrict: 'E',
template: '<div>{{name}} - 123</div>',
scope: { name:'&myName'}
}
});
the HTML:-
<create-directive my-name="bob" ></create-directive>
however, its failing to print out 'bob'
im failing to see why not?

Scope configuration is incorrect. It should be:
scope: {
name: '#myName'
}
Special character & is used to setup a function reference to the outer scope function.

Related

Angularjs - Pass optional parameter for Directive from HTML

I am trying to pass an optional parameter isvalid from my html to the directive. I have followed all the steps mentioned in documentation but it still looks like i am doing something wrong.. i am not able to read the value in my directive. can you let me know what am i doing wrong?
HTML
<customvideo isvalid="true"></div>
MY Directive
Update: I had simplified for questioning purpose and hence you were seeing $scope. I have updated the actual directive now
// Set the directive
angular
.module('custom.directives')
.directive('customvideo', customvideoDirective);
// Set the directive $injections
customvideoDirective.$inject = ['$Scope'];
function customvideoDirective($Scope)
{
return {
compile: compile,
restrict: 'A',
$Scope: {
isvalid: '=?'
}
};
function compile() {
console.log($Scope.isvalid); //this is undefined
}
}
})();
Change you $Scope property inside Directive Definition Object (DDO) should be changed scope. Also use link function instead of using compile, as compile function has access to only raw DOM, there will be no scope available in it. Even you can return and PreLink/PostLink from compile function, but in this case I believe using link would be appropriate.
angular.module('directives')
.directive('customvideo', function () {
return {
link: link,
restrict: 'A',
scope: {
isvalid: '=?'
}
}
);
function link(scope) {
console.log(scope.isvalid);
}
Found a way to work it out.. not sure if it is the best.. but hey.. it works :) Posting it here for those who come here for answers...
I was writing the syntax for compile wrongly... I changed it to
function compile(tElement, tAttrs, transclude)
{
// the tAttrs param has all the attributes associated with the element
console.log(tAttrs.isvalid);
}

iterating over array of objects using ng-repeat

I Know I am missing out on something which I am not able to figure out. Need your help guys.
Basically I want to create multiple thumbnails, for which, the data I am storing in a variable and then trying ng repeat to get the details, but no success. Please help. Here is the plunker for the same. Without directive, using ng-include, its working fine, but with directive, nothing is getting displayed.
directive code:-
app.directive('thumbnail', function() {
return {
restrict: 'E',
templateUrl: 'UI/templates/thumbnail.html',
scope: {
}
}
});
https://plnkr.co/edit/q9dWaLpYFusgwGhZDCYF?p=preview
app.directive('thumbnail', function() {
return {
restrict: 'AE',
templateUrl: 'UI/templates/thumbnail.html',
}
});
app.directive('thumbnail', function() {
return {
restrict: 'AE',
templateUrl: 'UI/templates/thumbnail.html',
}
});
removing isolated scope, will make the data defined in controller available in directive. if you still want to use isolated scope pass the data using = operator
Updated plunker withe the working with directive.
[https://plnkr.co/edit/Yr8DsPb3kt5Jz3CNFGnM?p=preview][1]

Accessing ng-repeat scope on a custom directive

I'm having a go at a directive which will dynamically load a template based on a scope value passed into it.
I am using ng-repeat on my directive, and am using the iterated item as an attribute property:
<my-form-field ng-repeat="field in customFields" field="field">
In my directive I have the following code to set the template being used.
(function() {
'use strict';
angular
.module('app')
.directive('myFormField', myFormField);
function myFormField() {
var directive = {
restrict: 'E',
scope: {
field: '='
},
link: function(scope){
scope.getContentUrl = function() {
return 'app/modules/form_components/form_field/' + scope.field.type + '-template.html';
}
},
template: '<div ng-include="getContentUrl()"></div>'
};
return directive;
}
})();
Whilst the above works (which I found from other posts), I wonder if there is a better way.
For example I have seen examples of calling a function on the templateUrl config option instead, and then in that function access the scope attributes being passed in. When I tried this way, my field attribute was a literal 'field' string value (they are objects in my customFields array), so I think at that point the scope variables had not yet been evaluated.
With this current solution I am using, all of my templates get wrapped in an extra div since I am using ng-include, so I am just trying to make the rendered markup more succinct.
Any suggestions\advice is appreciated.
Thanks

AngularJs attributes vs scope in directives

What is the difference while using variables though attributes vs scope while define directives? For example -
angular.module('tModule')
.directive('tModule', function() {
return {
restrict: 'E',
scope: true,
templateUrl: function(element, attributes) {
return attributes.variable1;
}
}
});
versus if I use scope. like below -
angular.module('tModule')
.directive('tModule', function() {
return {
restrict: 'E',
scope: {
variable1: "=variable1",
variable2: "=variable2"
},
templateUrl: function() {
return variable1;
}
}
});
What are the differences and advantages?
There are a few differences based on your example:
In your top example, specifying scope: true means to create a new instance of the parent scope. In the bottom example, using an object syntax means to create an isolated scope. So, when you pass parameters to a directive using the scope syntax like that, you are inherently creating an isolated scope for the directive.
If you want to take advantage of two-way data binding (=) or method invocation (&), then you'd want to use the second method of passing through scope instead of attributes.

Why is what I set in rootScope not available in a directive?

I am setting the following:
function appRun(
$rootScope
) {
$rootScope.abc = 99;
}
I am calling a directive like this:
<admin-retrieve-button ctrl="exam" home="home" Network="Network"></admin-retrieve-button>
Here's my directive:
app.directive('adminRetrieveButton', ['stateService', function (stateService) {
return {
scope: {
ctrl: '=',
home: '=',
Network: '=',
abc: '='
},
restrict: 'E',
template: "xxxx {{ abc }} dddd",
link: function (scope, element, attrs) {
scope.stateService = stateService;
scope.entity = attrs["entity"];
}
};
}]);
However when my HTML page comes up it shows:
xxxx dddd
Can someone tell me why the rootScope value of 99 does not show up?
Because you're declaring an isolate scope on your directive, thus creating a new parent less scope. One way to fix this would be to obviously explicitly pass in abc in your HTML:
<admin-retrieve-button ctrl="exam" abc="abc" home="home" Network="Network"></admin-retrieve-button>
Or you could change your directive to not create a scope of its own:
scope:false
or just leave the scope property alone (don't declare it), however passing in a directives dependencies through a scope of its own is good practice IMO, it's more explicit and gets rid of hidden dependencies.

Resources