Pass array in directive attributes - javascript

I want to pass array in the directive attribute. It doesn't work. I tried to pass an array in the attribute of a directive and nothing happened.
class Directive {
constructor () {
'ngInject';
let directive = {
restrict: 'E',
template: '<div class="btn-group">
<label class="btn btn-primary classButton"
ng-model="radioModel" uib-btn-radio="'First'"
config="{{config[0]}}">{{config[0]}}
</label>
</div>',
controller: Controller,
controllerAs: 'vm',
bindToController: true,
scope: {
config: '='
}
};
return directive;
}
}
class Controller {
constructor() {
'ngInject';
}
}
<directive config="First, Second"></directive>
How should I pass the array to the directive?

Maksim,
You need to pass a scope variable instead of a array constant here,
That is, declare a scope variable and assign this value to that variable like this,
$scope.myArray = ['Firs', 'Second'];
and now you can pass this scope variable to your directive.
<directive config="myArray"></directive>
It should work !!!

Related

how to call function after append html to the directive

viewBannerCtrl is the controller in that i'm using "customTable" directive
Here i'm not able to access "VBC.bannerAlert()" function from the directive
and i appended the code to directive but not able to access controller functions with append tag
.controller('viewBannerCtrl',function(){
vbc.bannerAlert = function(){
alert('success called in inside directive.....Hurry!!!!!!!!!!!!!!!!!!');
};
});
.directive('customTable', function customTable($compile) {
return {
restrict: 'EA',
templateUrl: 'app/admin/modules/common/views/custom_table.html',
scope: {
data: '=data',
dataLength: '=datalength',
filterDataArray: '=filterData',
imageData: '=imageData'
},
controller: customTableCtrl,
link:function(scope,element,attr){
var el = angular.element(document.getElementById('dyanamicActions'));
el.append('<button class="btn btn-danger btn-rounded btn-ef btn-ef-5 btn-ef-5b" ng-click="VBC.bannerAlert()"><i class="fa fa-trash"></i> <span>Deletess</span></button>');
$compile(el)(scope);
},
controllerAs: 'CTC',
bindToController: true
};
});
function customTableCtrl(MainService) {
var ctc = this;
};
}
<div custom-table data="VBC.getBannerlistData" datalength="VBC.totalItems"
table-headers="VBC.tableInit" image-data="'image'"
table-actions="VBC.editData" delete-model="VBC.openBannerDeleteModal">
</div>
You current directive has implemented using isolated scope like scope: { ... }. So directive don't have outer scope methods are available in it(didn't follow prototypal inheritance when scope are isolated).
You have to pass bannerAlert function expression to directive from its isolated scope using &. So that that function will get available inside directive scope.
For passing that function to directive you have to write attribute bannerAlert="bannerAlert()" on directive element. Like I've shown below.
Markup
<div custom-table data="VBC.getBannerlistData"
datalength="VBC.totalItems"
table-headers="VBC.tableInit"
image-data="'image'"
table-actions="VBC.editData"
delete-model="VBC.openBannerDeleteModal"
bannerAlert="bannerAlert()">
</div>
Code
scope: {
data: '=data',
dataLength: '=datalength',
filterDataArray: '=filterData',
imageData: '=imageData',
bannerAlert: '&bannerAlert' //<--added expression binding here
},

Alternative for ngInit inside custom directive

Assume I have a simple directive:
angular.module('app').directive('myDir', myDir);
function myDir() {
var directive = {
bindToController: true,
controller: null,
controllerAs: 'vm',
template: '<button ng-click="vm.myDirVar = 1">',
scope: {
myDirVar: '='
}
};
return directive;
}
If in the following example vm.var is undefined, my directive will not bind it to the isolated scope.
<my-dir my-dir-var="vm.var"></my-dir>
So in order to make it work, I'm using ng-init to set the default value for thevm.var, after that the binding to isolated scope works.
<my-dir my-dir-var="vm.var" ng-init="vm.var = var || 0"></my-dir>
The question is, how can I improve my directive so I can get rid of the ng-init while vm.var would still be binding even if it is undefined initially.
You can do something like:
var directive = {
bindToController: true,
controller: function(){
this.myDirVar = this.myDirVar || 0;
},
controllerAs: 'vm',
template: '<button ng-click="vm.myDirVar = 1">',
scope: {
myDirVar: '='
}
};
If is not a problem having a controller.

How can i change array in directive, and then reflect that change in my controller?

I made directive with isolated scope with "=" method, in that directive i pass empty array, then i push data on that array.... How that change can be reflected on original array in my controller?
Here is the example:
angular.module('myModule').controller('MyController', ['$scope', function($scope) {
$scope.test = [];
}]);
angular.module('myModule').directive('mydirective', function() {
return {
scope: {
test: "=",
bread: "="
},
restrict: 'E',
link: function(scope, element, attribute) {
scope.test.push('one more')
},
replace: true,
templateUrl: 'some template'
};
});
HTML
<div ng-controller='MyController'>
<mydirective test='test'></mydirective>
<div ng-bind='test'> </div>
</div>
When i push something on array i dont have a reflection of that in my controller.
How can i fix that?
Here's how to do what you are trying to achieve.
HTML
<!-- myCtrl contains the original array, which we push here to the scope as 'ctrl' -->
<div ng-controller='myCtrl as ctrl'>
<!-- we pass your directive 'ctrl.test', which tells angular to two-way bind to the
test property on the 'ctrl' object on the current scope -->
<mydirective test='ctrl.test'>
<!-- we're inside the isolate scope: test here refers to mydirective's idea of test,
which is the two-way bound array -->
<div ng-bind='test'></div>
</mydirective>
</div>
JS
angular.module('app', [])
.directive('mydirective', function() {
scope: {
test: '='
},
link: function($scope) {
$scope.test.push('one more');
}
})
.controller('myCtrl', function() {
this.test = [];
});
Any alterations to the array will now be reflected in the ng-bind. Please note that it is bad practice to place primitives on $scope without being part of an object (due to the mechanics of prototypical inheritance) so you'd want to change $scope.test to something else.

How to Create nested objects in isolated scope

So I want to create a nested struture on my nested scope inside a directive like this:
angular.module('myAddress').directive('myAddress', [function () {
return {
restrict: 'AE',
controller: 'myAddressController',
templateUrl: 'my-address.html',
scope: {
address: {
'form': '=addressForm',
'model': '=addressModel'
}
}
};
}]);
But I get an exception that undefined is not a function that I don't get if I remove the address nesting.
How do I put attribute arguments inside a named key on my scope?
Also, If I define $scope.address via the controller it doesn't work as well. But what will execute first? The scope: { 'form' = 'addressForm'} part in my directive or the controller's $scope.form?
With the scope property you define which $scope variables should pass to the directive scope and the type of data-binding.
If you want to create an nested structure within the directive $scope, you could create it in the directive controller function.
For example:
angular.module('myAddress').directive('myAddress', [function () {
return {
restrict: 'AE',
controller: 'myAddressController',
templateUrl: 'my-address.html',
scope: {
addressForm: '=', // Two-way databinding
addressModel: '='
},
controller: function($scope){
$scope.address = {
form: $scope.addressForm,
model: $scope.addressModel
}
},
link: function($scope,$element,$attributes){
//Your code here
}
};
}]);
You can also, define $scope.address in the module controller scope. Then your scope property in the directive should be look like this
scope: {
address: '='
}
UPDATE:
Another question is: Does your directive need an dedicated scope? If not you could set the scope property false. Then your directive can access the $scope variables in your module controller.

Inject a variable into an Angular Controller from a Angular Directive

Updating as there is some confusion as to what I am asking. I would like to use a directive to inject a variable into the controller used by that directive. I realize I can use the $scope for that, but I don't find that an intuitive solution.
Essentially I want my controller to have the proposal variable injected into it.
My intended usage:
<blah-directive proposal="proposal"></blah-directive>
The directive (so far):
app.directive('blahDirective', function () {
return {
restrict: 'E'
, transclude: true
, replace: true
, scope: {
proposal: '='
}
, templateUrl: 'blahTemp.html'
, controller: blahController
};
});
blahTemp.html
<form class="form-horizontal" role="form" name="myBidForm">
**{{ proposal }}**
</form>
this is displaying the value proposal variable in the $scope fine, but it is not what I want. Essentially I would like to define my controller like:
var blahController = function($scope, SomeOtherResource, proposal) {
}
If you want to inject locals into a controller use $controller.
Here is an example (plunker):
app.directive('blahDirective', function ($controller) {
return {
restrict: 'E',
scope: {
proposal : "="
},
transclude: true,
replace: true,
templateUrl: 'blahTemp.html',
link : function (scope, elm, attrs){
scope.proposal = {};
var locals = {
$scope: scope ,
proposal: scope.proposal
};
$controller('blahController', locals);
}
};
});

Categories