My directive code is:
(function() {
angular.module('app')
.directive('dynamicImage', dynamicImage);
function dynamicImage($timeout) {
return {
restrict: 'A',
scope: { dynamic:'&dynamicImage' },
link: function (scope, elem) {
scope.dynamic = function(){
//code here
}
}
};
}
})();
My Controller code is :
In controller How can I call??
function theMethodToBeCalled() {
$scope.dynamic();
}
My HTML:
<div class="col-xs-12" dynamic-image="theMethodToBeCalled">
<div class="meet_details_status_img" data-ng-repeat="user in meet.user" data-ng-if="user.extra.invitationStatus === 'pending'">
<img class="img-circle my-meets-status-img" ng-src="{{ user.displayPicture ? (imageURL + user.id) : 'assets/images/user_thumb.jpg' }}"
/>
</div>
</div>
Please Help me.
Thanks
You can expose an object from controller to directive and can define a method inside that object in the directive. Since you've access to the object which is exposed in directive so you can call any method defined in that directive.
Example -
(function() {
angular.module('app')
.directive('dynamicImage', dynamicImage);
function dynamicImage($timeout) {
return {
restrict: 'A',
scope: { dynamic:'&dynamicImage',methodList:'=' },
link: function (scope, elem) {
scope.methodList.dynamic = function(){
//code here
}
}
};
}
})();
In controller -
function CtrlFun($scope){
$scope.methodList = {};
$scope.callDirectiveMethod = function(){
$scope.methodList.dynamic();
}
}
HTML
<div dynamic-image method-list="methodList"> </div>
Related
Here i want to pass $scope.myData of app.js to the directive mcsaForm and use the object attributes in myTemplate.html. My code is working properly except the approach which i mentioned above.
app.js
myApp.controller("myCont", function($scope){
.
some code
.
.
$scope.getTypeOfEvent = function(typeOfEvent, idOfEvent)
{
if(typeOfEvent == "MCQ")
{
if(idOfEvent)
{
var indexOfEvent =$scope.namesTwo.Events.indexOf("idOfEvent")+1;
var valueAtIndex = $scope.namesTwo.Events[indexOfEvent].id;
$scope.myData = $scope.namesTwo[valueAtIndex];
console.log($scope.myData); // output: Object {eventId: "001", TimeOfEvent: "2", EventType: "MCQ"}
}
//fetchJsonDir.gettingContData;
$scope.mCSSQ(typeOfEvent,idOfEvent);
}
}
});
myDirective.js
videoCourseApp.directive("mcsaForm",['fetchJsonDir', function(fetchJsonDir){
return{
restrict: "C",
templateUrl: "assets/template_blocks/Preview_forms/myTemplate.html",
scope: {
myData: "="
},
compile: function(scope, element, attrs)
{
$("#mcss_option_list").append("Hello");
},
controller: function($scope){
$scope.onSubmitHidePanel = function()
{
$(".mcsa_form").fadeOut("slow", function(){
$(this).remove();
});-
}
}
}
}]);
myTemplate.html
<div id=mcss_option_list>
</div>
<div>
001, 2, MCQ//print myData.eventId, myData.TimeOfEvent or whatever..
</div>
Use your directive like
<div class="mcsa-form" my-data="myData"></div>
You will get the value in your directive's myTemplate.html
<div id=mcss_option_list>
{{myData.TimeOfEvent}}
</div>
I'm a bit stuck on an directive which add attributes and recompile the element.
If I had a scope on the directive ng-change is not triggered anymore (without it it works). I based my test on this answer
The HTML
<div ng-app="myApp">
<div ng-controller='testController'>
<div ng-repeat="field in fields">
<input type="text" ng-model="ngModel[field.fieldName]" property="{{formParams.getProperties(field.fieldName)}}" update-attr ng-change="test()" />
</div>
</div>
</div>
The directive:
angular.module('myApp', [])
.controller('testController', function ($scope) {
$scope.properties = {
"something": {
"style": "float:left;"
},
"something2": {
"style": "float:right;"
}
};
$scope.ngModel = {};
$scope.fields = [{
fieldName: 'something'
}, {
fieldName: 'something2'
}];
$scope.test = function () {
alert('i dont get triggered');
};
$scope.formParams = {
getProperties: function (fieldName) {
return $scope.properties[fieldName];
}
};
})
.directive('updateAttr', function ($compile) {
return {
restrict: 'A',
replace: true,
terminate: true,
scope: {
ngModel : '='
},
link: function (scope, elem, attrs) {
if (angular.isDefined(attrs['property']) && attrs['property'].lenght != 0) {
var json = JSON.parse(attrs['property']);
angular.forEach(json, function (value, key) {
elem.attr(key, value);
});
elem.removeAttr('property');
var $e = $compile(elem[0].outerHTML)(scope);
elem.replaceWith($e);
}
}
};
});
Here a fork of the fiddle to test with a scope on the directive: fiddle
Do you have any suggestion ?
I found why ng-change was not trigger so I share the answer:
When we add scope attribute on the directive, a new scope is created. So we have to use $scope.$parent for the compilation. I have updated the fiddle with the correction.
I am trying to implement the directive, in the directive, I want to $eval the values which contains the function name and parameter value:
Html page:
<select mydirective="action('pValue')">
AngularJS directive code:
app.directive('mydirective', function ($timeout) {
return {
restrict: 'A',
link: function ($scope, element, attr) {
$timeout(function () {
$scope.$eval(attr.mydirective);
});
}
}
What I am expected is it will invoke the action function define in scope and pass the pValue as function parameter. How can I make it work please?
What you want happen automatically, the function will invoke with the value, this is the purpose of eval:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.action = function(val) {
alert(val);
}
});
app.directive('mydirective', function($timeout) {
return {
restrict: 'A',
link: function($scope, element, attr) {
$timeout(function() {
$scope.$eval(attr.mydirective);
});
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
<div ng-app="plunker" ng-controller="MainCtrl">
<select mydirective="action('pValue')"></select>
</div>
For those whom looking for a way to pass $event info to custom directive method see example below:
TEMPLATE:
<div on-touch-end="onTouchEnd( 'some data' )">
TOUCH ME!
</div>
CONTROLLER:
$scope.onTouchEnd = function( data ) {
console.log("onTouchEnd event with data", data, event );
};
DIRECTIVE:
.directive('onTouchEnd', function() {
return {
restrict : 'A',
link : function( $scope, $element, $attr ) {
$element.on('touchend', function( event ) {
$scope.$apply(function() {
$scope.$eval( $attr.onTouchEnd );
});
});
}
}
})
Hello i have my directive:
myApp.directive('hoverDirective',function($document){
return function(scope, element, attr){
scope:{value:'foo'};
element('mouseover',function(event){
console.log(event);
});
}
});
And I have it working:
<div hover-directive>
{{value}}
</div>
But now I want to hardcode data in directive, and get it by factory.
I read about scope:{value:'foo'}. But i have error while i was putting it inside of return function.
Can anyone help ?
UPDATE: I try putting code inside of return function no results.
Please see here : http://jsfiddle.net/qeCDL/
HTML:
<div ng-app="app">
<div ng-controller="firstCtrl">
<div hover-directive></div>
</div>
</div>
JS:
var app = angular.module('app', []);
app.directive('hoverDirective', function () {
return {
scope: {},
restrict: 'AE',
controller: function () {
},
template: '<h3>{{value}}</h3>',
link: function (scope, element, attrs) {
scope.value = "hove me";
element.on('mouseover', function (event) {
console.log(scope.value);
});
}
};
});
app.controller('firstCtrl', function ($scope) {
});
I want this
$scope.name = 'Angular';
$scope.list = ['foo: {{name}}', 'bar: {{name}}'];
<div ng-repeat="template in list" compile="template"></div>
to be
<div real="foo: Angular"></div>
<div real="bar: Angular"></div>
So i use $compile:
$compileProvider.directive('compile', function ($compile) {
return function (scope, element, attrs) {
scope.$watch(
function (scope) {
return scope.$eval(attrs.compile);
},
function (value) {
//element.html(value);
//$compile(element.contents())(scope);
element.attr("real", value);
element.removeAttr("compile");
$compile(element)(scope);
}
);
};
})
but, it output:
<div real="foo: Angular"></div>
<div real="foo: Angular"></div>
<div real="bar: Angular"></div>
<div real="bar: Angular"></div>
so what's the problem ?
Demo: http://plnkr.co/edit/OdnriGpd7eMBtfp2u1b2?p=preview
Try this instead:
<div ng-repeat="template in list">
<div compile="template"></div>
</div>
DEMO
Explanation:
When you put your directive on the same element with ng-repeat and call $compile(element)(scope);, your element is recompiled including the ng-repeat, causing the ng-repeat to run one more time. When I also remove the ng-repeat in the directive, it works:
element.attr("real", value);
element.removeAttr("compile");
element.removeAttr("ng-repeat");
$compile(element)(scope);
DEMO
This solution is not recommended because we hard-code the element.removeAttr("ng-repeat");
Remember to also apply priority:1500 and terminal:true to the directive to avoid compiling again after angular has compiled the element:
$compileProvider.directive('compile', function($compile) {
return {
priority:1500,
terminal:true,
link: function(scope, element, attrs) {
scope.$watch(
function(scope) {
return scope.$eval(attrs.compile);
},
function(value) {
//element.html(value);
//$compile(element.contents())(scope);
element.attr("real", value);
element.removeAttr("compile");
$compile(element)(scope);
}
);
}
};
});
For more information about these 2 settings. Check out Add directives from directive in AngularJS
Alternatively, you can use the pre link function : http://plnkr.co/edit/VIOAX1akTPF68DYxZQcQ
angular.module('demo', [], function($compileProvider) {
$compileProvider.directive('compile', function($compile) {
return {
restrict:'A',
compile: function(celement, cattrs) {
return{
pre: function(scope,element,attrs){
var attribute = scope[attrs.compile];
element.attr('real',attribute);
element.removeAttr('compile');
$compile(element)(scope);
},
post: function(scope,ielmt,iattrs){
}
}
}
};
})
});
function Ctrl($scope) {
$scope.name = 'Angular';
$scope.list = ['foo: {{name}}', 'bar: {{name}}'];
}