Multiple Controller As Syntax with One Directive? - angularjs

I have Routes and Controllers like below
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {
templateUrl : '/data/user.html',
controller : 'UserController as usr'
})
.when('/add-schema', {
templateUrl : '/data/group.html',
controller : 'GroupController as grp'
})
}])
/*Note That I dont want to use $scope*/
.controller('UserController', function($http) {
var vm = this;
vm.total_rows = 90;
})
.controller('GroupController', function($http) {
var vm = this;
vm.total_rows = 60;
});
And I want to use only one pagination Directive for all pages , smth like this
.directive('datasPagination', function() {
return {
restrict: 'E',
template: '<ul class="pagination"><li>{{total_rows}}</li></ul>'
}
});
How to get the {{total_rows}} inside my Directive given that I use Controller As Syntax with different aliases and I dont use $scope ? . Above, I use "usr" and "grp" as Alias
Regards

Try to isolate the directive scope, this is useful when you want to build a reusable component...
APP.directive('datasPagination', function() {
return {
restrict: 'E',
scope: {
rows: "="
},
template: '<ul class="pagination"><li>{{rows}}</li></ul>'
}
});
<!-- where alias is the alias defined in controllerAs syntax -->
<data-pagination rows="alias.total_rows" />
further reading here

Related

Angualrjs- redirect from one controller to another

I have two controllers. I would like to use the other controller based on a dependancy value. I am not able to set this at the $route level. How can I essentially do this on in the main controller: Is this even possible?
angular.module('app').controller('Controller1', ['importantService', function(importantService) {
if (importantService.getValue) {
// Use this other controller Controller2 instead
}
});
You could put your 2 controllers in directives and have an ng-if in the template switch between the two, something like:
app.controller('MainCtrl', function($scope, importantService) {
$scope.importantValue = importantService.getValue;
});
app.directive('myFirstComponent', function() {
return {
restrict: 'E',
templateUrl: '/same/url/for/both',
controller: function() {/*...your controller 1*/}
};
});
app.directive('mySecondComponent', function() {
return {
restrict: 'E',
templateUrl: '/same/url/for/both',
controller: function() {/*...your controller 2*/}
};
});
and in your template
<div ng-if="importantValue === 1"><my-first-component></my-first-component></div>
<div ng-if="importantValue === 0"><my-second-component></my-second-component></div>
probably not the most orthodox solution but it will do what you're asking.

Change Directive variable inside a directive is not working

I am trying to change a controller variable inside a directive and this is my code:
the main controller is :
angular.module("app").controller('vehicleManagementController', ['$scope', 'toastr', '$filter' ,
function ($scope, toastr, $filter) {
.....
$scope.filteredDevices = //Some List
$scope.allDevices = [];
}
}]);
and the directive is :
angular.module('app').directive('advanceSearchDirective', ['deviceAdvancedSearchService', 'mapService', function (deviceAdvancedSearchService, mapService) {
return {
restrict: "E",
controller: 'myDirectiveController',
scope: { filteredDevices: '=filteredDevices' },
templateUrl: '/app/templates/advanceSearchDirective.html'
};
}]);
angular.module("app").controller(myDirectiveController( $scope) {
$scope.search = function() {
$scope.filteredDevices = [];
$scope.$apply();
}
});
the thing is it faild to run the apply() method through this error.
and here how i am using it :
<advance-search-directive filtered-devices="filteredDevices" model="$parent"></advance-search-directive>
I have access to $scope.filteredDevices inside the directive controller but when i change its value it doesn't change in the main controller. what am I doing wrong?
if you want to save the changes on the parent controller scope you should use
scope:false,
change the directive to :
return {
restrict: "E",
controller: 'myDirectiveController',
scope: false,
templateUrl: '/app/templates/advanceSearchDirective.html'
};
here is an useful article .

Why is callback function into directive controller not being recognized?

I'm trying to get a directive to work with its own controller:
http://jsfiddle.net/edwardtanguay/xfbgjun5/14/
However, when I click the button:
var template = '<button ng-click="vm.addItem()">add item</button>'+
'<ul><li ng-repeat="item in vm.items">{{item}}</li></ul>';
It tells me that:
Error: vm.add is not a function
even though I define controllerAs and bindToController:
return {
restrict: 'A',
scope: {
datasource: '=',
add: '&'
},
controller: controller,
controllerAs: 'vm',
bindToController: true,
template: template
};
and pass in a scope method from the main controller:
<div item-menu datasource="customers" add="addCustomer()"></div>
Why does it not recognize add as a function on vm?
ADDENDUM: The controller looks like this:
.controller('mainController', function ($scope) {
$scope.customers = ['First','Second','Third'];
$scope.score = 0;
$scope.addCustomer = function() {
$scope.score++;
}
})
You can find the answer to your question in this blog post
If you use Angular 1.3 you need to add to the directive the following line of code:
bindToController: true,
Check the blog post and the code snippets.
When you bind to attributes, you have to bind it to $scope, not the controller.
var controller = function($scope) {
var vm = this;
function init() {
vm.items = angular.copy($scope.datasource);
}
init();
vm.addItem = function() {
$scope.add();
vm.items.push('new one');
}
}
http://jsfiddle.net/xfbgjun5/15/

Angular scope property not accessible from directive in attribute

I have a controller like this:
var exampleController = function($scope, $stateParams){
$scope.myVariable = $stateParams.id;
console.log($scope.myVariable);
}
and a directive like:
var exampleDirective = function(){
return {
restrict: 'E',
scope : {
myVariable: '='
},
templateUrl: "myTemplate.html",
link: function($scope){
console.log($scope.myVariable);
});
};
}
in my html like:
<my-example myVariable="myVariable"></my-example>
Given the id in the url is 21, I got this:
21
undefiend
Do anybody know why I couldn't pass any $stateParams value so that the directive don't see it?
I've tried to pass a static value but it didn't worked too.
Tried in this way within the controller:
$scope.myVariable = 26;
You forgot the Angular convention for attribute names:
<my-example my-variable="myVariable"></my-example>

Can I require an adjacent directive?

I have two element-level directives, a search box and a search results. My markup is something like this (simplified):
<catalogue-search-box query="{{query}}">
<catalogue-search-results></catalogue-search-results>
I'm trying to access the search box controller from the search results directive, but the documentation suggests that in the directive's require property I can only find controllers on the same element or on the parent element. Is there a way to find controllers on adjacent elements?
After you comments here is how I would do it: use an object to hold all your state and pass it to both directives. Demo plunker
HTML
<body ng-controller="MySearchController">
<search-box search="mySearch"></search-box>
<search-results search="mySearch"></search-results>
</body>
JS
var search = angular.module('search', []);
//simulated service
search.service('Search', ['$timeout', '$q', function($timeout, $q) {
return {
findByQuery : function(query) {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve([query + ' result1', query + ' result2']);
console.log('resolved query ' + query);
}, 2000);
return deferred.promise;
}
};
}]);
search.controller('MySearchController', ['$scope', function($scope) {
$scope.mySearch = {
query : ''
}
}]);
search.controller('SearchBoxCtrl', ['$scope', 'Search', function($scope, Search) {
$scope.execute = function(search) {
console.log(search);
if(search.query && search.query.length > 3 && !search.running) {
search.running = true;
search.promise = Search.findByQuery(search.query).then(function(val) {
search.results = val;
});
}
};
}]);
search.directive('searchBox', function(){
return {
restrict: 'E',
scope : {
search : '='
},
controller: 'SearchBoxCtrl',
template : '<div ng-hide="search.results">Query: <input type="text" ng-model="search.query" ng-disabled="search.running"></input> <button ng-click="execute(search)" ng-disabled="search.running">Search</button></div>',
replace: 'true'
};
});
search.controller('SearchResultsCtrl', function(){
});
search.directive('searchResults', function(){
return {
restrict: 'E',
scope : {
search : '='
},
controller: 'SearchResultsCtrl',
template : '<div ng-show="search.results"><div ng-repeat="result in search.results">{{result}}</div></div>',
replace: true,
link : function(scope, element, attrs, ctrl){
}
};
});
PS:
Don't use p tags in directive templates as the root node. The html parser reports 2 nodes if you have p child nodes and angular has a requirement for a single root node.
You can further use the promise in the controller to register other functions to execute when the results come in.
One way I've been experimenting with since the question is having some kind of controller directive i.e.
<catalogue-search>
<catalogue-search-box query="{{query}}">
<catalogue-search-results></catalogue-search-results>
</catalogue-search>
I can then access the "controller directive" this using the parent (^) modifier in my require statement. Each directive can then talk to each other via the controller directive.
Does this seem sensible or is it overcomplicating things?

Resources