ng-bind isn't working in label with a custom directive - angularjs

I created a directive to add a hint-icon with a description for label, as the following:
propertyWindowModule.directive('hintIcon', {
restrict: 'A',
controller: HintIconController,
controllerAs: 'vm'
});
class HintIconController {
static $inject = ['$element', '$timeout'];
constructor(private $element:ng.IRootElementService,
private $timeout: ng.ITimeoutService) {
if(!_.isEmpty(this.$element.attr('hint-icon'))) {
this.$element.attr('title', this.$element.attr('hint-icon'));
this.$element.append($('<i class="tooltip-icon glyphicon glyphicon-question-sign">').attr('title', this.$element.attr('hint-icon')));
}
}
}
And in some views I used it in the label:
<label ng-bind="vm.label" hint-icon="test icon"></label>
The the ng-bind isn't working, but the hint-icon working well - I see the icon of the description with the tooltip, but with no label.

Actually when you define two directive in an element it will throw an exception : "Multiple directives for one scopes!". So you need to define your own ng-bind in hint-icon directive.
<label hint-icon="test icon" hint-icon-bind="vm.label"></label>
propertyWindowModule.directive('hintIcon', {
restrict: 'A',
scope: {
hintIconBind: '='
},
controller: HintIconController,
controllerAs: 'vm'
})
And you use it in your controller like:
scope.vm.hintIconBind

Related

How to give controller a name in a directive in Angular?

I have a directive defined this way:
angular
.module('ui-abc', [ 'xyz'])
.directive('computer', compute);
function compute( item) {
return {
restrict: "EA",
templateUrl: '../elements/src/template.html',
scope:{ qwerty : '=',}
controller: ['$scope','$sce', {
.........
}
The controller does not have a name, how can i add one ? I need this name so that I can refer to that controller inside my ui-router configuration. I tried to do this
function compute( item) {
return {
restrict: "EA",
templateUrl: '../elements/src/template.html',
controller: "controllerName"
}
app.controller("controllerName", function(){......
....
App is not defined in this module, it is defined in the main app.js controller file.
So, it does not work, what do I have wrong?
here, you app will be - var app = angular.module('ui-abc', [ 'xyz']);
And don't use controller: "something", if you don't have one. It'll be fine if you just skip that line.
In your directive you can put a parameter called controllerAs
directive.js
function compute( item) { return {
restrict: "EA",
templateUrl: '../elements/src/template.html',
controller: 'controllerName',
controllerAs: 'vm'
};}
you can now call the controller as vm in your template.html
template.html
<body><h1>{{ vm.variableName }}</h1></body>
You can add the param called 'controllerAs' as below:
function compute( item) {
return {
restrict: "EA",
templateUrl: '../elements/src/template.html',
controller: "controllerName",
controllerAs: 'cName'
};
}

Custom Directive inside a Directive using ControllerAs syntax

If I have two directives, one that's a table, and one that's a row. In this case the row is the same each time, and I just want to have it displayed twice in the index.html. <table-row> works in the index.html, but <table> does not why?
i.e.:
.directive('table', function() {
return {
restrict: 'E',
scope: {},
controller: 'table-ctrl',
controllerAs: 'ctrl',
bindToController: true,
template:`
<div>
<table-row></table-row>
<table-row></table-row>
</div>`
};
});
Table Row:
.controller('TableRowCtrl', function() {
this.toggle = function() {
this.toggleBool = !this.toggleBool;
}
//
this.toggleBool = false;
})
.directive('TableRow', function() {
return {
scope: {},
restrict: 'E',
replace: true,
controller: 'TableRowCtrl',
controllerAs: 'ctrl',
bindToController: true,
template: `
<div>
<span>Object</span>
<span>
<img ng-click="ctrl.toggle()" src="jpeg file" />
</span>
<span ng-if="ctrl.toggleBool"> Print </span>
</div>`
};
});
If table-row is the other directive that does everything and its controller is also what runs on clicks etc, how would I link in the table-row directive so that the table directive template works, and will call table-row multiple times.I would like to continue using the ControllerAs syntax instead of $scope.
It doesn't matter if you want to use controllerAs or not. From your code table directive has isolate scope and suppose if you want to iterate through table-row items by using ngRepeat directive it should be isolate scope as well.
Remember that every ngRepeat's item has own scope
For example:
.directive('table', function() {
return {
restrict: 'E',
scope: {},
controller: 'table-ctrl',
controllerAs: 'ctrl',
bindToController: true,
template:
<div ng-repeat="item in ctrl.items">
<table-row item="item"></table-row>
</div>`
};
});

angularjs: how to use controllerAs to access the property of the isolated scope directive in template

I usually use the controllerAs syntax in my Angularjs project, which I think will be more clear in the template.
But in the current web app,I came into an issue as following:
function FirstCtrl() {
this.name = 'First Controller';
}
function fooDirective() {
return {
scope: {
testData:'='
},
name: 'ctrl',
controller: 'FirstCtrl',
controllerAs: 'foo',
template: '<div>{{ foo.name }} {{testData}} {{foo.testData}}</div>',
link: function ($scope, $element, $attrs, $ctrl) {
console.log($ctrl.name);
}
};
}
angular
.module('app', [])
.directive('fooDirective', fooDirective)
.controller('FirstCtrl', FirstCtrl);
the html part is as following:
<div ng-app="app">
<foo-directive test-data="'newdata'"></foo-directive>
</div>
and the live demo is here:
https://jsfiddle.net/baoqger/rbp1wyfa/
And my confusing point is in the template part:
template: '<div>{{ foo.name }} {{testData}} {{foo.testData}}</div>',
The {{testData}} can work well. But the {{foo.testData}} can't. How to fix the issue so I make access the property in the isolated scope object in controllerAs way.
You want to add bindToController: true to your directive definition:
function fooDirective() {
return {
scope: {
testData:'='
},
name: 'ctrl',
controller: 'FirstCtrl',
controllerAs: 'foo',
bindToController: true,
template: '<div>{{ foo.name }} {{testData}} {{foo.testData}}</div>',
link: function ($scope, $element, $attrs, $ctrl) {
console.log($ctrl.name);
}
};
}
Applicable documentation is here (note you have to scroll up a bit bc of their floating menu/header).

Two directives, respective pair of controllers and same templateUrl

I am novice in AngularJS. I want to use one template for two directives. In deal, the first directive overrides the behavior of the second. But I've specified different controllers for each of them. I think the reason is isolation of scopes by controllers. I need that the first controller execute its own filterChanged() function and so does the second controller. Same with fields: montage, pay, cancel and inactivity. I tried to manipulate the scope (true, 'isolate', false, {}), transclude (true, false, 'element'), scope fields ('#', '=', '&'). 'controllerAs' and 'controllerBindTo' are unsuitable for my task, because I want to this throw separate controller files.
Help me plz. Hands fall.
Source code below.
filter.html
<div class="filter">
<p class="text-center"><b ng-bind="::title"></b></p>
<div class="contact-item-requires-filter">
<div class="contact-item-require">
<input id="contact-item-montage-filter" class="contact-item-require-montage" type="checkbox"
ng-model="filter.montage"
ng-change="filterChanged()">
<label title="Монтажи" for="contact-item-montage-filter"></label>
</div>
</div>
directive1.js
angular.module('qualityControl')
.directive('requiresFilterDirective', function() {
return {
templateUrl: '../templates/pages/quality/filter.html',
controller: 'requiresFilterController'
}
});
directive2.js
angular.module('qualityControl')
.directive('usersFilterDirective', function() {
return {
templateUrl: '../templates/pages/quality/filter.html',
controller: 'usersFilterController'
}
});
UPDATED.
Add variable with '&', this is function declaration
.directive('requiresFilterDirective', function () {
return {
restrict: 'AE',
scope: {
functionToCall: '&',
someData: '='
},
templateUrl: '../templates/pages/quality/filter.html',
link: function (scope, elem, attrs) {
scope.functionToCall();
console.log('scope.someData', scope.someData);
}
}
})
Usage:
<requires-filter-directive function-to-call="myFunctOne()" some-data="yourJsonObject"></requires-filter-directive>
<requires-filter-directive function-to-call="myFunctTwo()" some-data="yourJsonObject"></requires-filter-directive>
And declare these functions in your main controller:
$scope.myFunctOne = function() {
alert("111")
};
$scope.myFunctTwo = function() {
alert("222")
};
$scope.yourJsonObject = {'aaa':123};

Pass every attribute of model in ng-repeat to directive isolate-scope

I'm using a directive with an ng-repeat
<page ng-repeat='page in pages' id='{{page.id}}' title='{{page.title}}'></page>
And my directive :
app.directive('page', function(){
return {
restrict: 'EA',
scope: {
id: '#',
title: '#'
},
templateUrl: 'views/tpl/page.html',
controller: 'PageController'
});
Is there any way to avoid having to pass in manually all the attributes into the directive's isolate scope ? My goal would be to populate the directive's scope automatically with every attribute in the "page" object.
Thanks !
You can pass the whole page object. Directives Guid
html:
<page ng-repeat='page in pages' page-object='page'></page>
js:
app.directive('page', function(){
return {
restrict: 'EA',
scope: {
pageObject: '='
},
templateUrl: 'views/tpl/page.html',
controller: 'PageController'
});

Resources