How to render directive in controller? - javascript

for example there is a directive
(function() {
angular.module("mydir", []).directive("mydir", mydir);
function mydir() {
return {
restrict: "EA",
templateUrl: "app/components/myDir/myDir.template.html",
};
}
}());
and in the controller I'm trying to do the following
var temp = "<div mydir></div>";
var content = $compile(temp)({});
compile returns a div element, but would like to template of directive.

Directives are named using camel case, however, in the HTML they use a hyphen (myDir -> my-dir).
<div my-dir></dir>

Your code seems to work for me.
Javascript:
var app = angular.module('defaultmod',[]);
app.directive('mydir',function(){
return {
restrict:'AE',
template:'<span>hello</span>'
};
});
app.controller('defaultctrl', function($scope,$compile){
var temp = "<div mydir></div>";
var content = $compile(temp)({});
alert(content[0].outerHTML);
});
HTML
<div ng-app="defaultmod">
<div ng-controller="defaultctrl">
</div>
</div>
JSFiddle
http://jsfiddle.net/vcps7yy0/

Related

AngularJS Calling the controller method from directive

Prompt as from a directive to cause a method of the controller.
Directive
app.directive('scroll', function($location){
return{
restrict: 'A',
link: function(scope, element, attrs){
element.on('scroll', function(){
let fh = $('#ngview').height();
let nh = Math.round($(element).height() + $(element).scrollTop());
if(fh == nh){
//Here we do what we need
}
})
}
}
});
HTML markup
<div class="col-md-12 middle-body" scroll>
<div ng-show="showUserModal" ng-include="'partial/loginModal.html'"></div>
<div class="user-loader" ng-show="loading">
<div class="spinner"></div>
</div>
<div ng-view id="ngview">
</div>
</div>
app is the main application module
var app = angular.module('app',
[
'ngRoute',
'lastUpdateModule',
'selectedByGenreModule',
'currentFilmModule',
'httpFactory',
'userModule',
'accountModule'
]);
The controller from which you want to call the method is described in a separate file
and connects via require
const SelectedByGenreModule = require('../controllers/selectedByGenre.controller.js')
and passed as a dependency to the main module
So it is from this controller that I need to call the method in the directive.
Tell me how to do it correctly. I left through $rootScope but it did not work out
As far as I know, the directive has the same scope as the controller in which it is located. That is, the directive is in the controller which is the parent for the controller from which you need to call the method.
It sounds like you want your directive to trigger an action defined by your controller. I'd recommend passing the function to the directive via the scope property. See the example below.
var app = angular.module('ExampleApp', []);
app.directive('scroll', function($location) {
return {
restrict: 'A',
scope: {
scroll: '='
},
link: function(scope, element, attrs) {
element.on('scroll', function() {
let fh = $('#ngview').height();
let nh = Math.round($(element).height() + $(element).scrollTop());
if (fh == nh) {
scope.scroll();
}
})
}
}
});
app.controller('ExampleCtrl', function($scope) {
$scope.onScroll = function() {
console.log('Scrolled!')
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="ExampleApp" ng-controller="ExampleCtrl">
<div class="col-md-12 middle-body" scroll="onScroll">
<div ng-show="showUserModal" ng-include="'partial/loginModal.html'"></div>
<div class="user-loader" ng-show="loading">
<div class="spinner"></div>
</div>
<div ng-view id="ngview">
</div>
</div>
</div>
You can require parent controllers using the require property when defining the directive, the ^^ tells angular to look up the DOM for a parent, otherwise it will only look on the local element.
app.directive('scroll', function($location){
return{
restrict: 'A',
require: '^^selectedByGenreCtrl', // Use the correct controller name here
link: function(scope, element, attrs, selectedByGenreCtrl){
element.on('scroll', function(){
let fh = $('#ngview').height();
let nh = Math.round($(element).height() + $(element).scrollTop());
if(fh == nh){
//Here we do what we need
}
})
}
}
});

How to merge few partials via templateUrl AngularJS

I'm thinking is there a way to merge partial views via templateUrl in the directive in AngularJS?
Let's say I have directive:
.directive('mergeThisStupidPartials', function () {
var mainpartial = "mainpartial.html",
var template2 = "partial2.html",
var template3 = "partial3.html"
return {
restrict: "E",
templateUrl: mainpartial,
//merge mainpartial with template2 and template3
//link function need?
};
});
I will have few more partials and they will be renered in some conditions (for example:
one view with mainpartial with partial2, partial4, partial6
another view with combined mainpartial with partial1 and partial5)
I'm wondering this way, because my partials have a lot of HTML code, I can put them into template instead templateUrl but then there will be a huge block of code. I want to avoid that.
Is it possible in AngularJS?
Just ng-include all partials in mainpartial.html:
<div ng-include="template1"></div>
<div ng-include="template2"></div>
<div ng-include="template3"></div>
<!-- etc -->
Make sure to assign the partial urls to $scope variables:
.directive('mergeThisStupidPartials', function () {
var mainpartial = "mainpartial.html";
return {
restrict: "E",
templateUrl: mainpartial,
controller: ['$scope', function ($scope) {
$scope.template1 = "partial1.html";
$scope.template2 = "partial2.html";
$scope.template3 = "partial3.html";
// Etc
}]
};
}]);
You can also use the paths directly in mainpartial.html:
<div ng-include="'partial1.html'"></div>
<div ng-include="'partial2.html'"></div>
<div ng-include="'partial3.html'"></div>
Notice that I included extra quotes, so angular interprets the attributes as strings.

Angular Directive parameter Issue

I am creating a directive which will take the arguments passed to it from html and populate the fields in the template. The code for directive is like below.
(function(){
angular.module("MyApp",{})
.directive("myDirective",function(){
var MyLink = function(scope,element,attr){
scope.title = attr.title;
}
return{
restrict : 'EA',
transclude:true,
templateUrl:"directive.html",
link:MyLink
}
});
}())
The directive.html is like
<div >
<span data-ng-bind="title"></span>
</div>
The main page is like
<div ng-app="IndexApp" ng-controller="IndexController">
<my-directive title="hello"></my-directive>
this is a test
</div>
My issue is that why is hello not getting displayed ?
Link to plunker is here
Your module declaration was wrong, you were using {} instead of []. If you also wanted to declare the directive in another module then you need to add the dependency to your indexApp (I've done so in this plunker).
http://plnkr.co/edit/s02VmgFfWhstmVhVVrUa?p=preview
index.js
(function(){
angular.module("IndexApp",['myDirectives'])
.controller("IndexController",function($scope){
$scope.title = "this is to test";
});
}())
directive.js
(function(){
angular.module("myDirectives", [])
.directive("myDirective",function(){
var MyLink = function(scope,element,attr){
scope.title = attr.title;
}
return{
restrict : 'EA',
templateUrl:"directive.html",
link:MyLink
}
});
}())

Angular directive to add content rather than overwrite

I am trying to write a directive that will show a "loading" message over a div while the data is fetched from the server.
Thus far I've managed to get this:
.directive('dataLoadingPanel', function () {
return {
templateUrl: '/Utilities/loadingPanelBox.html',
scope: {
panelData: '=',
loadingMessage: "#"
}
};
})
loadingPanelBox.html has this:
<div class="modal-dialog" style="background-color: white;width:300px;height:46px;padding-top:16px;top:30px;padding-left:40px;border-radius: 4px;" ng-hide="panelData">
<img src="/images/BlueSpinner.gif" style="margin-top:-2px" /> {{loadingMessage}}
</div>
This actually does most of what I want, the panel is shown until the data is returned at which point it disappears.
Unfortunately it also overwrites the contents of the div it's placed on, so in this instance:
<div data-loading-panel panel-data="myData" loading-message="Loading Data">Hello There</div>
the Hello There is never seen. This seems to be a function of my using a template.
Is there a way of stopping this overwriting happening or maybe some way of adding the content other than with a template.
I use this:
BlockUI
This is a module which is very easy to use. There is a nice tutorial on the page that fills all of your needs.
Thanks to #Amiros I've made it work slightly differently.
Here's the directive and controller code:
.controller('dataLoadingPanelController', [
'$scope', '$timeout', function($scope, $timeout) {
$timeout(function() {
$scope.setBoxSize();
});
} ])
.directive('dataLoadingPanel', function () {
return {
restrict: 'EA',
scope: {
panelData: '=',
loadingMessage: "#"
},
templateUrl: '/Content/Utilities/loadingPanelBox.html',
link: function (scope, element, attr) {
var elMessage = element.find('.loading-message-area');
var elBox = element.find('.loading-dialog');
scope.setBoxSize = function() {
var messageSize = parseInt(elMessage.css('width').replace(/px$/, ""));
var parentSize = parseInt(element.parent().css('width').replace(/px$/, ""))
var newBoxSize = messageSize + 70;
elBox.css('width', newBoxSize + 'px');
var newBoxPosition = (parentSize / 2) - (newBoxSize / 2);
elBox.css('margin-left', newBoxPosition + 'px');
};
},
controller: 'dataLoadingPanelController'
};
})
The html file is:
<div style="position:absolute;color:black;font-weight:normal;">
<div class="modal-dialog loading-dialog" style="border:1px solid #1f4e6c;background-color: white;height:46px;padding-top:14px;top:30px;padding-left:20px;border-radius: 4px;" ng-hide="panelData">
<img src="/images/BlueSpinner.gif" style="margin-top:-2px" /> <span class="loading-message-area">{{loadingMessage}}</span>
</div>
</div>
which is pretty simple and means that the usage is as follows:
<div class="panel-body">
<data-loading-panel panel-data="myData" loading-message="Loading Data"></data-loading-panel>
{{myData}}
</div>

Call parent controllers' function from directive in angular

jsfiddle
I have a ng-click within a directive named ball. I am trying to call MainCtrl's function test() and alert the value of ng-repeat's alignment of ball.
Why cant i recognize the MainCtrl's test function?
var $scope;
var app = angular.module('miniapp', []);
app.controller('MainCtrl', function($scope) {
$scope.project = {"name":"sup"};
$scope.test = function(value) {
alert(value);
}
$scope.test2 = function(value) {
alert('yo'+value);
}
}).directive('ball', function () {
return {
restrict:'E',
scope: {
'test': '&test'
},
template: '<div class="alignment-box" ng-repeat="alignment in [0,1,2,3,4]" ng-click="test(alignment)" val="{{alignment}}">{{alignment}}</div>'
};
});
html
<div ng-app="miniapp">
<div ng-controller="MainCtrl">
{{project}}
<ball></ball>
</div>
</div>
You need to pass the test() method from the controller into the directive...
<div ng-app="miniapp">
<div ng-controller="MainCtrl">
{{project}}
<ball test="test"></ball>
</div>
</div>
Change & to = in directive:
scope: {
'test': '=test'
}
Fiddle: http://jsfiddle.net/89AYX/49/
You just need to set the controller in your directive as:
controller: 'MainCtrl'
so the code for your directive should look like:
return {
restrict:'E',
scope: {
'test': '&test'
},
template: '<div class="alignment-box" ng-repeat="alignment in [0,1,2,3,4]" ng-click="test(alignment)" val="{{alignment}}">{{alignment}}</div>',
controller: 'MainCtrl'
};
the one way is to not isolate a directive scope...just remove the scope object from directive.
Another way is to implement an angular service and put a common method there, inject this service wherever you need it and in the directive call function that will be insight isolated scope and there call a function from directive

Categories

Resources