I want to be able to use the variable "videoUrlId" from the controller 'useSpreadsheetData' below in my directive 'meetings'. How can I do this? I have looked at require but could not get it to work.
Controller:
app.controller('useSpreadsheetData', ['$scope', '$sce', 'getSpreadsheetData',
function($scope, $sce, getSpreadsheetData){
for(var x in videos) {
if(videos[x].switchValue) {
var videoUrlId = videos[x].videoUrl;
$scope.videoUrlId = videoUrlId;
break;
}
}
};
Directive:
app.directive('meetings', [ 'getCalendar', '$timeout', '$window',
function(getCalendar, $timeout, $window){
return {
restrict: 'E',
templateUrl: 'scripts/directives/meetings.html',
controller: 'useSpreadsheetData',
link: function(scope){
//Use videoUrlId variable here
}
}
}]);
Since you mentioned you attempted to use require, I have to assume the meetings directive will be a child element somewhere within the useSpreadsheetData controller, however without seeing your HTML, we can't be sure.
As you're not utilizing an isolate scope, your directive will prototypically inherit from the parent controller above itself, in this case useSpreadsheetData. As a result, we can simply get videoUrlId by accessing it via an interpolated expression: {{videoUrlId}}. Note the template in the meetings directive. It'll also be available within link or controller via scope.videoUrlId and $scope.videoUrlId, respectively.
Plunker: http://plnkr.co/edit/MZIgXEiku4Z2PLzl3apz
HTML
<div ng-controller="useSpreadsheetData">
Controller: <code>videoUrlId = {{videoUrlId}}</code><br>
Directive: <meetings></meetings>
</div>
JavaScript
app.controller('useSpreadsheetData', function($scope) {
var videos = [service call];
for (var x in videos) {
if (videos[x].switchValue) {
var videoUrlId = videos[x].videoUrl;
$scope.videoUrlId = videoUrlId;
break;
}
}
});
app.directive('meetings', ['$timeout', '$window',
function($timeout, $window) {
return {
restrict: 'E',
template: '<code>videoUrlId = {{videoUrlId}}</code>'
}
}
]);
Output
Controller: videoUrlId = /1
Directive: videoUrlId = /1
Related
I am new to AngularJS. Can anyone tell me with example that how to call a custom directive in a scope function of another controller.
For example I have a controller with a function as follows:
angularApp.controller('sample_Ctrl', function ($scope, $http, $timeout, $rootScope, $location) {
$scope.showReport = function(id) {
};
});
I created a customDirective as follows:
var showModalDirective = function ($timeout) {
return {
restrict: 'E',
templateUrl: '/Partials/template1.html',
};
};
angularApp.directive('showModal', showModalDirective);
So how to call this directive in the showReport function, and how can I pass id to template URL?
You can't call directive in controller. It should be a service.
Or you can use directive in view:
Directive:
var showModalDirective = function ($timeout) {
return {
restrict: 'E',
scope: {
modalId: '='
},
templateUrl: '/Partials/template1.html',
};
};
angularApp.directive('showModal', showModalDirective);
Controller:
angularApp.controller('sample_Ctrl', function ($scope, $http, $timeout, $rootScope, $location) {
$scope.showModal = false;
$scope.showReport = function(id) {
$scope.showModal = true;
$scope.modalId = id;
};
});
View:
<div ng-if="showModal">
<show-modal modal-id="modalId"></show-modal>
</div>
showModal directive is call when showModal variable is true.
To use your directive first u need to create HTML element with same name as your directive then provide data for that directive from your controller. Suppose there is a div in your html page.
<div show-modal> </div>
Then on this page your template1.html will call internally through directive and suppose there is some html element in template1.html like
code in your controller -
angularApp.controller('sample_Ctrl',function() {
$scope.firstName= "My First Name"
})
I have a isolated directive, my controller looks like:
app.controller('ZacksController', ['$scope', '$http', 'ngDialog', '$timeout', function($scope, $http, ngDialog, $timeout){
//some code here
}]);
The HTML in the file looks like:
<div class="income-older-block" ng-show="selectedAge!=1">
<income-form></income-form>
</div>
I have a directive in related HTML folder,
app.directive("incomeForm", ['$timeout', function ($timeout) {
function link($scope) {
var hello = function () {
alert("1");
}
$timeout(hello, 0);
}
return {
restrict: 'E',
templateUrl: "app/zacks/your-income/income-form/income-form.html",
link: link,
controller: function ($scope, $timeout) {
$scope.$watch("zacks.AgeRet.value",function(newValue,OldValue,scope){
if (newValue){
alert((newValue));
}
});
}
}
}]);
I want to alert after I load the directive in the page, the alert appears at initial page itself. May I know what to do?
The actual problem is I'm using a rz-slider and want to initialize it once the directive is loaded to DOM., as its not taking the values provided. Is there any other approach for this problem?
<rzslider rz-slider-model="zacks.AgeRet.value" rz-slider-floor="zacks.AgeRet.floor" rz-slider-ceil="zacks.AgeRet.ceil"></rzslider>
In case if the timeout works, I'm planning to initialize something like this:
$timeout(function () {
$scope.$broadcast('rzSliderForceRender');
});
UPDATE
Added a controller in the directive, so now I'm able to get the value when I move the slider, but still not able to initialize the value of the slider.
I kind of found 2 solutions for these kind of problems, but still not serving the purpose of what I really need with rz-slider.
Solution 1
HTML:
<div ng-controller="ZacksController">
<after-render after-render="rzSliderForceRender">element</after-render>
</div>
JS:
var app = angular.module('myApp',[]);
app.directive('afterRender', ['$timeout', function ($timeout) {
var def = {
restrict: 'E',
link: function (scope, element, attrs) {
$timeout(scope.$eval(attrs.afterRender), 0); //Calling a scoped method
}
};
return def;
}]);
app.controller('ZacksController', ['$rootScope', '$scope', '$http', ' $timeout', function($rootScope, $scope, $http, $timeout){
$scope.rzSliderForceRender = function()
{
alert('Fired!');
};
}]);
Solution 2
HTML:
<div class="income-older-block" ng-show="selectedAge!=1">
<income-form></income-form>
</div>
JS:
app.controller('ZacksapiController', ['$rootScope', '$scope', '$http', 'ngDialog', '$timeout', 'dataService', function($rootScope, $scope, $http, ngDialog, $timeout, dataService){
$scope.$watch('selectedAge', function(newValue, oldValue) {
if (newValue !== oldValue) {
$timeout(function() {
alert("reCalcViewDimensions");
$scope.$broadcast('rzSliderForceRender'); // This is not working, but alert works.
}, 0);
}
});
Update:
Triggered the window resize event inside the $timeout, but this would be a temporary hack. Would be great if someone help me out with the real approach to solve the problem.
$timeout(function() {
window.dispatchEvent(new Event('resize'));
$scope.$broadcast('rzSliderForceRender');
}, 0);
I'm new to angular and can't figure out how to call a directive function from the template. I have some fuctionality that will be reused throught the app and figured I would just make a directive with all the functionlity needed, that can easily be shared accross different modules. While searching for answers I came across this post: how-to-call-a-method-defined-in-an-angularjs-directive
which seems like a good solution. However, I can't seem to figure out why my directive method showPolicy() is not being called.
// controller:
(function(){
'use strict';
angular.module('releaseAppsModule')
.controller('releaseAppsController', releaseAppsController);
releaseAppsController.$inject = ['$rootScope',
'storageFactory',
'releaseAppsFactory',
'$modal',
'$translate',
'getIconFactory',
'$scope',
'$filter'];
function releaseAppsController($rootScope, storageFactory, releaseAppsFactory, $modal, $translate, getIconFactory, $scope, $filter) {
var vm = this;
vm.policyControl = {};
...
// controller template:
<tr ng-repeat="policyRelease in regionRelease.policyReleases | orderBy:vm.orderByField:vm.reverseSort" ng-if="policyRelease.status == 'NEW' || policyRelease.status == 'SCHEDULED'">
<td>
<policy control="vm.policyControl" release-item="policyRelease" class="release-apps-app-btn app-release-data"></policy>
</td>
// directive:
(function(){
'use strict';
angular.module('myApp')
.directive('policy', policy)
function policy() {
var directive = {
restrict: 'E',
link: link,
replace: true,
scope: {
releaseItem: '=',
control: '='
},
template: '<a ng-click="vm.policyControl.showPolicy({releaseItem: releaseItem});">{{ releaseItem.policy.name }}</a>'
};
return directive;
function link(scope, el, attr) {
scope.internalControl = scope.control || {};
scope.internalControl.showPolicy = function (releaseData) {
...
} // showPolicy
scope.internalControl.showPolicyModal = function(response, releaseData) {
...
} // showPolicyModal
} // link
} // policy
})();
In your template, you're trying to call vm.policyControl.showPolicy() which is undefined on your current directive scope, as Angular is attempting to find
[directiveScope].vm.policyControl.showPolicy()
You'll need to change the ng-click function to internalControl.showPolicy(), as that is referencing the actual object that the directive's scope has available.
I have referred to the previously asked question here -> same kind of question
but the answers did not help.
This is my master HTML:
<!--ss.com header starts here-->
<ss-header show="showHeader"></ss-header>
<!--ss.com header ends here-->
The {{headerHTML}} doesn't show the HTML in the template below:
This is my directive template - ss_header.html:
<header data-ng-show="{{show}}">
<div class="ss-header" data-ng-bind-html="headerHTML|convertAsHtml"></div>
</header>{{headerHTML}}
<div data-ng-show="{{show}}">Sample text to show ng-show is working properly in this directive.</div>
This is my directive.js
smartPrintApp.directive("ssHeader", ['$compile', function($compile) {
return {
restrict: "E", //directive for element only
//replace: true, //replace the custom tag
scope:{
show:'=show'
},
link: function(scope, element, attrs) {
scope.$watch(attrs.unsecureBind, function(newval) {
element.html(newval);
$compile(element.contents())(scope);
});
},
templateUrl: 'common/header/ss_header.html',
}
}]);
And this is my controller:
var smartPrintApp = angular.module("smartPrintApp",['ngRoute','ngResource','ngCookies', 'ngAria', 'ngAnimate']);
smartPrintApp.filter("convertAsHtml", ['$sce', function($sce){ return $sce.trustAsHtml}]);
smartPrintApp.controller("dotComController",['$scope', '$resource', 'serviceInfo', 'fetchLocalData', 'fetchServiceData', '$sce', '$window', '$http', '$compile', '$interpolate', function($scope, $resource, $service, fetchLocalData, fetchServiceData, $sce, $window, $http, $compile, $interpolate) {
/* Get Data from Server */
var reqData = {
"key1":"value1",//variables to send if needed
"key2":"value2"//variables to send if needed
};
var generalServ = new fetchServiceData($service.api.SERV_RESP);
generalServ.save(reqData).$promise.then(function(response){
/* Site Layout Modifications */
$scope.headerHTML = $interpolate(response.siteLayout.headerHtmlContent)($scope);
$scope.showHeader = response.siteLayout.headerEnabled;
/* Site Layout Modifications */
},function(err){
console.log('error in fetching service data')
});
/* Get Data from Server */
}]);
Any help is appreciated.
It doesn't show because you're using isolated scope but haven't passed in the header html. So currently {{headerHTML}} in your directive template is undefined. Change your isolated scope to:
scope:{
show:'=show',
headerHTML: '=header'
},
And your HTML to:
<ss-header show="showHeader" header="headerHTML"></ss-header>
I'm trying to pass in the url for the template via a scope variable. The scope will not change so the template doesn't need to update based on it, but currently the scope variable is always undefined.
<div cell-item template="{{col.CellTemplate}}"></div>
Ideally the directive would be:
.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) {
return {
scope: {
template: '#template'
},
templateUrl: template // or {{template}} - either way
};
}])
This doesn't work however. I've tried a lot of different permutations in accomplishing the same concept, and this seems the closest, however it still doesn't work.
.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) {
return {
scope: {
template: '#template'
},
link: function (scope, element, attrs) {
var templateUrl = $parse(attrs.template)(scope);
$http.get(templateUrl, { cache: $templateCache }).success(function (tplContent) {
element.replaceWith($compile(tplContent)(scope));
});
}
};
}])
I've also tried using ng-include, but that also doesn't evaluate scope variables before compiling. The CellTemplate value is coming from a database call so is completely unknown before evaluation. Any suggestions for getting this working would be greatly appreciated!
Edit:
I'm using angular 1.0.8 and am not able to upgrade to a newer version.
You are not far off at all.
You don't need to use an isolated scope for the directive. You can pass the templateUrl like this:
<div cell-item template="col.CellTemplate"></div>
Then add a watch to detect when the template value changes:
.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) {
return {
restrict: 'A',
link: function(scope , element, attrs) {
scope.$watch(attrs.template, function (value) {
if (value) {
loadTemplate(value);
}
});
function loadTemplate(template) {
$http.get(template, { cache: $templateCache })
.success(function(templateContent) {
element.replaceWith($compile(templateContent)(scope));
});
}
}
}
}]);
Here is a working Plunker: http://plnkr.co/edit/n20Sxq?p=preview
If you don't want to deal with the linking logic yourself, or you want the isolate scope, I think this is simpler:
.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) {
return {
scope: {
template: '#template'
},
template: "<div ng-include='template'></div>"
};
}])
or:
template:"<ng-include src='template'></ng-include>"
It's an old post but I thought its useful if anyone lands in here for the answer.
You can try the templateUrl function as #caub mentioned in a comment. Same can also be used for components.
.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) {
return {
templateUrl: function(element, attrs) {
return attrs.template || 'someDefaultFallback.html';
}
};
}]);
We don't need any of the injected dependencies here. Hope this helps someone.