AngularJS directive as attribute - make array available in directive - angularjs

I have this html fragment with my directive asScrollTop as attribute:
<div data-as-scroll-top>
<div data-ng-repeat="chatMessageOfUser in vm.chatMessagesOfUser">
<!-- use chatMessageOfUser -->
</div>
</div>
and this is my directive:
(function() {
'use strict';
angular
.module('myProject.common')
.directive('asScrollTop', asScrollTop);
function asScrollTop(validateService) {
var directive = {
restrict: 'A',
link: link
};
return directive;
////////////
function link(scope, element, attr) {
console.log(element);
element.on('scroll', function() {
if(element[0].scrollTop <= 0) {
// here I need vm.chatMessagesOfUser or the first entry of the
// vm.chatMessagesOfUser array
}
});
}
}
})();
My question now would be how I can make the the vm.chatMessagesOfUser array available in directive?

You can defined scope in directive like
var directive = {
restrict: 'A',
scope: { yourList: '=yourList' },
link: link
};
return directive;
function link(scope, element, attr) {
console.log(scope.yourList);
};
and set value in html markup
<div data-as-scroll-top your-list="vm.chatMessagesOfUser"></div>

Since your attribute directive uses the existing scope, the variables are on that scope.
function link(scope, element, attr) {
console.log(element);
element.on('scroll', function() {
if(element[0].scrollTop <= 0) {
// here I need vm.chatMessagesOfUser
console.log(scope.vm.chatMessaagesOfUser);
// or the first entry of the
// vm.chatMessagesOfUser array
console.log(scope.vm.chatMessangerOfUser[0]);
}
});
}

Related

Custom directive with dynamic template and binding parent scope to ng-model

I have a view that contains a template specified in a custom directive. The template that is used in the custom directive depends on 'dynamicTemplate':
View:
<div ng-controller="MyController">
<custom-dir dynamicTemplate="dynamicTemplateType"></custom-dir>
<button ng-click="ok()">Ok</button>
</div>
View's Controller:
myModule
.controller('MyController', ['$scope', function ($scope) {
$scope.dynamicTemplateType= 'input';
$scope.myValue = "";
$scope.ok = function()
{
// Problem! Here I check for 'myValue' but it is never updated!
}
Custom Directive:
myModule.directive("customDir", function ($compile) {
var inputTemplate = '<input ng-model="$parent.myValue"></input>';
var getTemplate = function (templateType) {
// Some logic to return one of several possible templates
if( templateType == 'input' )
{
return inputTemplate;
}
}
var linker = function (scope, element, attrs) {
scope.$watch('dynamicTemplate', function (val) {
element.html(getTemplate(scope.dynamicTemplate)).show();
});
$compile(element.contents())(scope);
}
return {
restrict: 'AEC',
link: linker,
scope: {
dynamicTemplate: '='
}
}
});
In this above example, I want 'myValue' that is in MyController to be bound to the template that is in my custom directive, but this does not happen.
I noticed that if I removed the dynamic templating (i.e. the contents in my directive's linker) and returned a hardcoded template instead, then the binding worked fine:
// If directive is changed to the following then binding works as desired
// but it is no longer a dynamic template:
return {
restrict: 'AEC',
link: linker,
scope: {
dynamicTemplate: '='
},
template: '<input ng-model="$parent.myValue"></input>'
}
I don't understand why this doesn't work for the dynamic template?
I am using AngularJS 1.3.0.
Maybe you should pass that value into your directives scope, instead of only dynamicTemplate, i think it should work.
You have a good answer about directives scope here: How to access parent scope from within a custom directive *with own scope* in AngularJS?
Hope I was of any help.
js directive :
angular.module('directive')
.directive('myDirective', function ($compile) {
var tpl1 ='<div class="template1">{{data.title}}</div>';
var tpl2 ='<div class="template2">Hi</div>';
var getTemplate = function (data) {
if (data.title == 'hello') {
template = tpl1;
}
else {
template = tpl2;
}
return template;
};
var linker = function (scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$render = function () {
// wait for data from the ng-model, particulary if you are loading the data from an http request
if (scope.data != null) {
element.html(getTemplate(scope.data));
$compile(element.contents())(scope);
}
};
};
return {
restrict: "E",
require: 'ngModel',
link: linker,
scope: {
data: '=ngModel'
}
};
});
html :
<my-directive
ng-model="myData">
</my-directive>
js controller:
$scope.myData = {title:'hello'};

Get HTML inside directive declaration

I have a directive that can contain some HTML inside it. How can I get it? I have tried link and compile but I am getting the HTML that is defined in the template. Here is my view:
<my-directive ng-model="ctrl.SomeField">
<p> This is the HTML I want! <p>
</my-directive>
Here is my directive:
return {
restrict: 'E',
scope: {
ngModel: "="
},
template: "<p>This is the HTML that is being returned from compile and link!</p>" +
"<p>This is not the HTML that I want!</p>"
link: {
pre: function preLink(scope, element, attrs) {
var html = element.html(); //returns the html in the directive template
},
post: function postLink(scope, element, attrs) {
var html = element.html(); //returns the html in the directive template
}
},
compile: function(element, attrs){
var html = element.html(); //returns the html in the directive template
}
}
How do I get the HTML from my view and not from my directive template?
Edit: Here is an example - http://plnkr.co/edit/z6gFOrGG01jKoKwISHcW?p=preview
Here is my solution! http://plnkr.co/edit/OlRyBN1I0jCkAREIKVeC?p=preview. Basically I just needed to use another directive to do some fancy transclusion stuff in a link step.
Here is the directive:
function returnFn() {
return {
link: {
pre: function (scope, element, attr, ctrl, transclude) {
if (transclude) {
transclude(scope, function (clone) {
element.append(clone);
});
}
}
}
}
}
return [returnFn];

AngularJS: How to get directive's name in the linking function?

I would like to use directive's name inside the linking function. How could I get it?
app.directive('myDirective', function() {
return {
link: function(scope, element, attrs) {
// How could I get directive's name here (i.e. 'myDirective')?
}
};
});
It is possible inside compile function of directive.
directives.directive('myNamedDir', ['$compile', function ($compile) {
return {
compile: function(cElem, cAttrs, transclude) {
var name = this.name;
return function linkFunction(){
//use name
}
}
}]);
Simply define it outside the injection:
var name = 'myDirective';
app.directive(name, function() {
return {
link: function(scope, element, attrs) {
console.log(name); // --> myDirective
}
};
});
app.directive('myDirective', function() {
return {
link: function(scope, element, attrs) {
console.log(arguments.callee.directiveName); // --> myDirective
}
};
});
the arguments.callee.caller property deprecated in JavaScript

Angular JS passing parameter to scope function from directive

Assume that I have a directive like this
<div my-directive callback='doSomething(myArg)'></div>
angular.module('directives').directive('myDirective', function() {
return {
restrict: 'A',
scope: {
callback: '&'
},
link: function(scope, element, attrs) {
element.bind('someEvent', function() {
scope.callback({myArg: 'bla'});
});
}
}
});
If I want to pass a parameter to my scope's function, I have to do scope.callback({myArg: 'bla'}). I wonder if there's a way pass the argument without having to specify its name?
Use can use shared service in this case and inject it to directive:
angular.module("yourAppName", []).factory("mySharedService", function($rootScope){
var mySharedService = {};
mySharedService.values = {};
mySharedService.setValues = function(params){
mySharedService.values = params;
$rootScope.$broadcast('dataPassed');
}
return mySharedService;
});
And after inject it to directive. For example:
app.directive('myDirective', ['mySharedService', function(mySharedService){
return {
restrict: 'C',
link: function (scope, element, attrs) {
mySharedService.setValues(//some value//);
}
}
}]);
Then, you can get necessary value in controller.
function MyCtrl($scope, mySharedService) {
$scope.$on('dataPassed', function () {
$scope.newItems = mySharedService.values;
});
}

Angular - directive link isnt called

I have wrote a directive which has a link function which isnt beeing called, the templae is injected to the DOM
function() {
'use strict';
// Define the directive on the module.
// Inject the dependencies.
// Point to the directive definition function.
angular.module('app').directive('nvVideo', ['$window', nvVideo]);
function nvVideo ($window) {
// Usage:
//
// Creates:
//
var directive = {
link: function(scope, element, attrs) {
alert('ggg');
},
restrict: 'EA',
template: '<div id="slot1">video slot</div>'
};
return directive;
}
})();
HTML
<div ng-app='app'>
<n-video></n-video>
</div>
Directive
angular.module('app', [])
.directive('nVideo', ['$compile', function ($compile) {
return{
restrict: 'EA',
template: '<div id="slot1">video slot</div>',
link: function(scope, element, attrs) {
alert('ggg');
}
}
}]);
JSFIDDLE

Resources