I want to load my Angular Directive when my class change.
I have a directive who get the route and when this directive can get a route she set on a class in a div child.
But when the div child have the class, the directive don't run.
Route directive :
angular.module('myApp').directive('index', ['$rootScope','usersEntity', '$location', '$timeout',function($rootScope,usersEntity, $location, $timeout){
return {
restrict: 'E',
templateUrl: 'index',
replace: true,
controller: function ($scope, $element, $attrs) {
$scope.user = function () {
return usersEntity;
};
$scope.location = function () {
return $location.path().replace('/', '');
};
$rootScope.$on('$locationChangeStart', function (event) {
$scope.routeMap = {
'login': 'users-log'
};
if ($scope.location().length < 1) {
$scope.route = '';
} else {
$.each($scope.routeMap, function (index, value) {
if (index == $scope.location()) {
$scope.route = value;
}
});
}
});
},
link: function() {
}
}
}]);
Thanks and sorry for my perfect English ;)
Related
With my below angular1.x script code for image annotation I have searched for a solution to solve my conversion error but I didn't get many equalents of angular1.x code in angular4. The error is a runtime error for angular1.x when I try to convert into Angular4. See below.
For $inject I use #inject but it is quite difficult to use it in my code for converting angular 1.x image annotation to angular4 image annotation.
Image annoation in angular1.x
------------------------------
annotoriousAnnotateDirective.$inject = ['annotoriousService', 'setTimeout()'];
annotoriousAnnotateDirective(annotoriousService, setTimeout(()=> {
service = {
restrict: 'A',
link: annotateLink,
priority: 100
},
return service;
link.$inject = ['$scope', '$element', '$attributes'];
annotateLink($scope, $element, $attributes)=> {
if ($attributes.src) {
annotoriousService.makeAnnotatable($element[0]);
} else {
$element.bind('load', function () {
$scope.$apply(function () {
annotoriousService.makeAnnotatable($element[0]);
});
});
}
}
}, 200);
annotoriousDirective.$inject = ['$compile', '$rootScope', '$http', '$parse', '$timeout', 'annotoriousService'];
annotoriousDirective($compile, $rootScope, $http, $parse, $timeout, annotoriousService)=> {
let service = {
restrict: 'E',
scope: {
open: '=',
options: '=',
onOpen: '&',
onLoad: '&',
onComplete: '&',
onCleanup: '&',
onClosed: '&'
},
require: 'annotorious',
link: link,
controller: controller,
controllerAs: 'vm'
};
return service;
controller.$inject = ['$scope'];
controller($scope) {
}
link.$inject = ['$scope', '$element', '$attributes'];
function link($scope, $element, $attributes, controller) {
var cb = null;
$scope.$watch('open', function (newValue, oldValue) {
//console.log("watch $scope.open(" + $scope.open + ") " + oldValue + "->" + newValue);
if (oldValue !== newValue) {
updateOpen(newValue);
}
});
$scope.$on('$destroy', function () {
$element.remove();
});
init();
updateOpen(newValue) {
if (newValue) {
init(newValue);
} else {
if (options.annotationsFor) {
let annotatables = $(options.annotationsFor);
annotatables.each(function (idx) {
let item = this;
annotoriousService.makeAnnotatable(item);
});
}
}
}
init(open) {
let options = {
//href: $attributes.src,
annotationsFor: $attributes.annotationsFor,
onOpen() {
if (this.onOpen && this.onOpen()) {
this.onOpen()();
}
},
onLoad() {
if (this.onLoad && this.onLoad()) {
this.onLoad()();
}
},
onComplete() {
onComplete();
if (this.onComplete && this.onComplete()) {
this.onComplete()();
}
},
onCleanup() {
if (this.onCleanup && this.onCleanup()) {
this.onCleanup()();
}
},
onClosed() {
$scope.$apply(function () {
$scope.open = false;
});
if ($scope.onClosed && $scope.onClosed()) {
$scope.onClosed()();
}
}
};
if (options) {
Object.assign(options, this.options);
}
for (let key in options) {
if (options.hasOwnProperty(key)) {
if (typeof(options[key]) === 'undefined') {
delete options[key];
}
}
}
if (typeof(open) !== 'undefined') {
options.open = open;
}
$timeout(function () {
if (options.annotationsFor) {
$(options.annotationsFor).each(function (i) {
var itemToAnnotate = this;
annotoriousService.makeAnnotatable(itemToAnnotate);
});
}
}, 0);
}
My error code:
I found equalent for #Inject in angular4 ,
import { Inject } from '#angular/core';
import { ourservice } from 'servicepath';
export class{
constructor(#Inject(Ourservice / Directive/ etc) private ourservice){
//our functionality
}
}
If any corrections please let me know, I am still looking solution for Image annotation in angular4
I am injecting a serivce into a directive and for some instance this service returns undefined can anyone explain what I am doing wrong?
Here is a plunker of the code below. https://plnkr.co/edit/H2x2z8ZW083NndFhiBvF?p=preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.players = ["A","B","C"];
});
app.factory('PlayerListS', [function() {
var playerList = [];
function getList() {
return playerList;
}
function addToList(name) {
playerList.push(name);
}
return {
addToList :addToList,
getList: getList
}
}]);
app.directive("player",['PlayerListS', function (PlayerListS) {
return {
restrict: 'E',
scope: {
person:'#person',
add:'&add'
},
replace: false,
templateUrl: "player.html",
controller: function($scope, $element, $compile) {
$scope.add = function(name) {
PlayerListS.addToList(name);
console.log(PlayListS.getList());
}
}
};
}]);
You have a typo in your console because of which the code is throwing an error. Change your directive the following way
app.directive("player",['PlayerListS', function (PlayerListS) {
return {
restrict: 'E',
scope: {
person:'#person',
add:'&add'
},
replace: false,
templateUrl: "player.html",
controller: function($scope, $element, $compile) {
$scope.add = function(name) {
debugger;
PlayerListS.addToList(name);
console.log(PlayerListS.getList());
}
}
};
}]);
Working Demo: https://plnkr.co/edit/HhmOYyoZAhm6vvXp3puC?p=preview
When opening a bootstrap ui modal, if you prefer to use a directive, rather than separately a templateUrl and controller, how can you then in the controller of the directive for the modal, access $uibModalInstance in order to close the modal or whatever you need to do? Also, how can we pass items without having to add it as an attribute on the template?
angular.module('myModule', ['ui.bootstrap'])
.directive('myDirective', ['$timeout', function ($timeout) {
var controllerFn = ['$scope', '$uibModal', function ($scope, $uibModal) {
$scope.names = ['Mario','Wario','Luigi'];
$scope.openModal = function () {
var modalInstance = $uibModal.open({
animation: true,
template: '<my-modal>',
size: 'lg',
resolve: {
items: function () {
return $scope.names;
}
}
});
};
}];
return {
restrict: 'E',
templateUrl: '/Folder/my-directive.html',
controller: controllerFn,
scope: {
}
};
}])
.directive('myModal', ['$timeout', function ($timeout) {
var controllerFn = ['$scope', function ($scope) {
}];
return {
restrict: 'E',
templateUrl: '/Folder/my-modal.html',
controller: controllerFn,
scope: {
}
};
}]);
I use something like that to send parameter to modal, add an element to array and give it back to directive.
// Directive who open modal
.directive('myDirective', ['$timeout', function ($timeout) {
var controllerFn = ['$scope', '$uibModal', function ($scope, $uibModal) {
// Base array
$scope.names = ['Mario','Wario','Luigi'];
$scope.openModal = function () {
// Modal instance
var modalInstance = $uibModal.open({
animation: true,
template: '<my-modal>',
size: 'lg',
controller: 'myDirectiveModalCtrl',
controllerAs: '$modalController',
resolve: {
// Provide namesInModal as service to modal controller
namesInModal: function () {
return $scope.names;
}
}
});
// When modal close, fetch parameter given
modalInstance.result.then(function (namesFromModal) {
$scope.names = namesFromModal;
}, function () {
// $log.info('Modal dismissed at: ' + new Date());
});
};
}];
return {
restrict: 'E',
templateUrl: '/Folder/my-directive.html',
controller: controllerFn,
scope: {
}
};
}])
// Modal controller
.controller('myDirectiveModalCtrl', ['$uibModalInstance','namesInModal',
function ($uibModalInstance, namesInModal) {
// Use same name set in myDirective.controllerAs
var $modalController = this;
// Get provided parameter as service
$modalController.names = namesInModal;
// Add new element
$modalController.names.push('peach');
// Return modal variable when close
$modalController.ok = function () {
$uibModalInstance.close($modalController.names);
};
$modalController.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
]);
In the directive's link function, $uibModalInstance is available on the scope object.
I want to call alertForm directive in loginForm directive. Where I want call 'alertForm' directive in 'loginForm' is highlighted as //i want to call here
alertForm directive
angular.module('myApp')
.directive('alertForm', function () {
return {
templateUrl: 'app/directives/alert/alertForm.html',
restrict: 'E',
scope: {
topic: '=topic',
description: '=description'
},
controller: function($scope) {
$scope.words = [];
this.showAlert = function() {
$scope.description.push("hello");
};
}
};
});
loginForm directive
angular.module('myApp')
.directive('loginForm', function() {
return {
templateUrl: 'app/directives/loginForm/loginForm.html',
restrict: 'E',
scope: {
successCallback: '&',
errorCallback: '&',
emailField: '='
},
link: function (scope, element, attrs) {
},
controller: function ($rootScope, $scope, authenticationService) {
$scope.loginFormData = {};
$scope.inProgress = false;
$scope.onLogin = function (form) {
if (form.$valid) {
$scope.inProgress = true;
authenticationService.loginUser('password', $scope.loginFormData).then(function () {
$scope.successCallback({formData: $scope.loginFormData});
}, function (err) {
$scope.inProgress = false;
if (err.message) {
**// i want to call here**
}
});
}
}
}
};
});
You can use require config of directive.
When a directive requires a controller, it receives that controller as
the fourth argument of its link function. Ref : Documentation
You can implement this in your code
angular.module(‘myApp')
.directive('loginForm', function() {
return {
templateUrl: 'app/directives/loginForm/loginForm.html',
restrict: 'E',
require:'alertForm',
scope: {
successCallback: '&',
errorCallback: '&',
emailField: '='
},
link: function (scope, element, attrs, alertFormCtrl) {
scope.alertFormCtrl = alertFormCtrl;
},
controller: function ($rootScope, $scope, authenticationService) {
$scope.loginFormData = {};
$scope.inProgress = false;
$scope.onLogin = function (form) {
if (form.$valid) {
$scope.inProgress = true;
authenticationService.loginUser('password', $scope.loginFormData).then(function () {
$scope.successCallback({formData: $scope.loginFormData});
}, function (err) {
$scope.inProgress = false;
if (err.message) {
// Calling showAlert function of alertFormCtrl
$scope.alertFormCtrl.showAlert();
}
});
}
}
}
};
});
Add the following line in the app/directives/loginForm/loginForm.html :
<alertForm topic="something" description = "something" ng-if="showAlert"></alertForm>
Now inside the loginForm directive's controller : // i want to call here
use
$scope.showAlert = true;
Note: you can use some variable to setup the topic and description as well inside the alertForm.
i am trying to consume iCheck check box using a directive. my directive is setup like this.
.module('app').directive('bootstrapCheck', ['$timeout', '$parse', function ($timeout, $parse) {
return {
compile: function (element, $attrs) {
var icheckOptions = {
checkboxClass: 'icheckbox_minimal',
radioClass: 'iradio_minimal'
};
var modelAccessor = $parse($attrs['ngModel']);
return function ($scope, element, $attrs, controller) {
var modelChanged = function (event) {
$scope.$apply(function () {
modelAccessor.assign($scope, event.target.checked);
});
};
$scope.$watch(modelAccessor, function (val) {
var action = val ? 'check' : 'uncheck';
element.iCheck(icheckOptions, action).on('ifChanged', modelChanged);
});
};
}
};
}]);
my check-boxes are in ng-repeat. i want to send the current object to function to process it further. my html is setup like this.
<input type="checkbox" ng-model="item.isSelected" ng-change="onChangeEvent(item)" bootstrap-check>
modelChanged gets triggered each time i change any check-box. but i am trying to access item inside modelChanged function to process it further. please guide.
You can pass the item to directive scope and access it inside the link function. Along with item you can also pass the onChangeEvent handler to the directive. Try this.
JS
angular.module('app').directive('bootstrapCheck', ['$timeout', '$parse', function ($timeout, $parse) {
return {
scope: {
item: '=',
onChangeEvent: '&'
},
compile: function (element, $attrs) {
var icheckOptions = {
checkboxClass: 'icheckbox_minimal',
radioClass: 'iradio_minimal'
};
var modelAccessor = $parse($attrs['ngModel']);
return function ($scope, element, $attrs, controller) {
var modelChanged = function (event) {
//Here $scope.item will give you the item
//This will trigger the parent controller's onChangeEvent set in the directive markup
$scope.onChangeEvent({ item: $scope.item });
$scope.$apply(function () {
modelAccessor.assign($scope, event.target.checked);
});
};
$scope.$watch(modelAccessor, function (val) {
var action = val ? 'check' : 'uncheck';
element.iCheck(icheckOptions, action).on('ifChanged', modelChanged);
});
};
}
};
}]);
HTML
<input type="checkbox"
ng-model="item.isSelected"
item="item"
on-change-event="onChangeEvent(item)" bootstrap-check>