Custom Directive inside a Directive using ControllerAs syntax - angularjs

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>`
};
});

Related

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};

Not able to render angular directive templateURL inside ng-init method

I am facing issue while rendering directive inside nginit method.
first directive :
Controller :
$scope.addDetails(asset) {
asset.label = "<div window></div>";
};
return {
restrict: "EA",
scope: true,
controller: "demoController",
controllerAs: "vms",
template:
"<div data-ng-repeat = 'data in vms.details' ng-init='vms.addDetails(data);'" +
</div>"
};
window directive:
return {
restrict:"AE",
templateURL: "infowindow.html"
};
With the below approach it worked with me we shouldn't do any complex logic(DOM rendering) when we use ng-repeat with ng-init. if so we need to construct the directive after the data is rendered.
$scope.details= {asset:1,description:"sample text"};
$scope.addLabel(asset) {
asset.label = "sample text to be shown in other directive";
};
return {
restrict: "EA",
bindToController: {details:'='}
scope: true,
controller: "demoController",
controllerAs: "vms",
template:
"<div data-ng-repeat = 'data in vms.details' ng-init='vms.addLabel(data);'" +
"<div window label-text=data.label></div>" +
</div>"
};
window directive:
return {
restrict:"AE",
bindToController:{labelText: '#'},
scope:true,
templateURL: "infowindow.html"
};
infowindow.html
<div>{{vms.labelText}}</div>

AngularJS directive: scope with named controller

I have the example below.
HTML:
<body ng-controller="MainCtrl as MgtCtrl">
<p>Hello {{MgtCtrl.name}}!</p>
<p>Result is {{MgtCtrl.result}}!</p>
<output-content data="MgtCtrl.name" result="MgtCtrl.result"></output-content>
</body>
JavaScript:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
var MgtCtrl = this;
MgtCtrl.name = 'World';
MgtCtrl.result = "no";
MgtCtrl.changeLabel = function() {
alert('changeLabel');
MgtCtrl.result = 'yes';
}
});
app.directive('outputContent', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'outputContent.html',
scope: {
data: '=',
changeLabel: '&',
result: '='
},
controller: 'MainCtrl',
controllerAs: 'MgtCtrl'
};
});
ouputContent.html:
<div>
{{data}}
<button ng-click="MgtCtrl.changeLabel()">Change</button>
</div>
Plunker is: http://plnkr.co/edit/BW8VDyCaRnRgxE8I9JJy
I would like the result to be 'yes' when I click on the 'Change' button.
It doesn't work because of the named controller.
Could you please explain to me how to write the directive to do so ?
Regards.
You never was binding the scope variables to the named controller in the directive.
You must add the attribute bindToController: true to the directive definition like this plunker:
http://plnkr.co/edit/2QdnkpeuTM6adG9KoyJT?p=preview
Directive code:
app.directive('outputContent', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'outputContent.html',
scope: {
data: '=',
changeLabel: '&',
result: '='
},
controller: 'MainCtrl',
controllerAs: 'MgtCtrl',
bindToController: true
};
});
This go to add the data and result binding to the respective directive controller.
I think in this case you don't need to specify controller in the directive.
app.directive('outputContent', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'outputContent.html',
scope: {
data: '=',
changeLabel: '&',
result: '='
}
};
});
Also html shoul be updated:
<body ng-controller="MainCtrl as MgtCtrl">
<p>Hello {{MgtCtrl.name}}!</p>
<p>Result is {{MgtCtrl.result}}!</p>
<output-content data="MgtCtrl.name" result="MgtCtrl.result" change-label="MgtCtrl.changeLabel()"></output-content>
</body>

AngularJs Multiple Directive

I am working on multiple directive, this is already existing framework so I dont want to disturb the existing components.
This is my HTML
<div title="test" mydirective>
This is my directive, this has templateUrl with it and this template has another directive getting loaded.
.directive('myDirective', function ($filter) {
restrict: 'A',
replace: true,
transclude: true,
scope: {
title: '#'
},
templateUrl: 'partial/partialtemplate.tpl.html'
});
My Partial Template html looks like this
<div newdirective title="{{title}}"></div>
This is my newdirective
.directive('newDirective', function ($filter) {
restrict: 'A',
replace: true,
transclude: true,
scope: {
title: '#'
},
templateUrl: 'partial/newpartialtemplate.tpl.html',
controller: function ($scope, $attrs) {
//here if I try to print my title I still get {{title}}
console.log($attrs.title);
}
});
So what could the issue be, I the second directive being called even before the template data is written or anything wrong?

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