Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
80
rated 0 times [  87] [ 7]  / answers: 1 / hits: 15615  / 11 Years ago, sat, november 16, 2013, 12:00:00

I have a custom directive which loads a navigation block from a webservice call.
I am trying to click on one of those navigation links which I put a ng-click in.
I am trying to click on the link which should call the function called within the ng-click. That function should execute, but it is not.



Here is my routing



var cartangularPublicShoppingApp = angular.module('cartangularPublicShoppingApp', [
'ngRoute',
'CategoriesController',
'CategoryServices',
'CategoryNavigationServices',
'MenuModule'
]);
cartangularPublicShoppingApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/cart', {
templateUrl: 'partials/public/cart.html',
controller: 'CartCtrl'
}).
when('/categories/:categoryId', {
templateUrl: 'partials/public/categories.html',
controller: 'CategoriesController'
}).
otherwise({
redirectTo: '/categories'
});
}]
);


Here is the custom directive



angular.module('MenuModule', [])
.directive('myCustomer', function() {
return {
restrict: 'E',
templateUrl: './partials/public/customer.html',
controller: function($scope, $sce, CategoryNavigationService) {

var z = CategoryNavigationService.getCategoryNavigation().success(function(data){
$scope.categoryNavigation = data;
var navHTML = createCategoryNavigationBar(data);
var t = $sce.trustAsHtml(navHTML);
$scope.panes = t;

}).error(function(data){

var error = Get confident, stupid!;
var t = $sce.trustAsHtml(error);
$scope.panes = t;
});
function createCategoryNavigationBar(categoryNavigation){
var test = ;
var categoryId;
var catNavArray = categoryNavigation.categoryNavigationArray;
for(categoryId in catNavArray){
var currentCategoryNavigation = categoryNavigation.categoryNavigationArray[categoryId];
var string = '<li> <a href=javascript:void(0); name=categoryId ng-click=getProductsForCategory()>' + currentCategoryNavigation.categoryName + </a>;
test = test + string;

var count = 0;
var countingNavArr = currentCategoryNavigation.categoryNavigationArray;
for(var countingObject in countingNavArr){
count++;
}
if(count > 0){
var innerCategoryId;
test = test + <ul>;
for(innerCategoryId in currentCategoryNavigation.categoryNavigationArray){
var innerCategoryNavigation = currentCategoryNavigation.categoryNavigationArray[innerCategoryId];
var innerTest = createCategoryNavigationBar(innerCategoryNavigation);
test = test + innerTest;
}
test = test + </ul>;
}
test = test + </li>;
}
test = '<ul id=menu>' + test + '</ul>';
return test;



}

}
};
});


Here is the controller that get's routed to my html fragment that I am showing the directive in.



var categoriesControllers = angular.module('CategoriesController', []);

categoriesControllers.controller('CategoriesController', ['$scope', '$routeParams' , '$location', 'CategoryService',
function($scope, $routeParams, $location, CategoryService) {

var categoryId = $routeParams.categoryId;
getProductsByCategoryIdServiceCall(CategoryService, categoryId);

$scope.getProductsForCategory = function(){
var categoryId = 4;
getProductsByCategoryIdServiceCall(CategoryService, categoryId);

}
function getProductsByCategoryIdServiceCall(CategoryService, categoryId){
CategoryService.getProductsByCategoryId(categoryId).success(function(data){
$scope.productsDTO = data;
$scope.name = David M Pugh;
}).error(function(data){
$scope.name = David Q Pugh;
$scope.name = data;
});

}

}]);


Here is code fragment from categories.html that contains the custom directive:



   <div class=row-fluid>
<div class=span12>
<div class=navbar>
<div class=navbar-inner>
<div class=container style=width: auto;>
<div class=span5></div>
<div class=span2>
<div id=currentCategoryDropBoxMenu>

</div>
</div>

</div>
</div>
</div>
</div>
</div>
<br />
<my-customer></my-customer>
<br />


I have tried changing the javascript method called inside ng-click to be like:
ng-click=getProductsForCategory as well.



both results in the method getProductsForCategory not being called when the link is clicked



Does anyone have any idea what my problem is?



thanks,



David



EDITED INFO*
Hey folks, thanks for looking into this problem. It is still ongoing, but I added an extra test to my html fragment for my custom directive



<div ng-bind-html=panes></div>
<a href=javascript:void(0); ng-click=getProductsForCategory()>testing</a>


Before the only line was the first tag which was the div.
I added the 2nd line to see if it was perhaps the binding of the html directly to the div tag in the directive, or if there was a problem with the directive's configuration elsewhere.



The second tag I added should be a standard ng-click operation. my 2nd a href tag does
call the function getProductsForCategory().
So it does appear to be due to my binding of my html string to the div element for the directive.



The problem is that my navigation structure i am building can have infinite nested child elements (it's basically a suckerfish select box).



This means I will have to use recursion to map out every parent child navigation
structure...in a directive...


More From » angularjs

 Answers
8

I came up with a solution for my project.
Here is the routing section



var cartangularPublicShoppingApp = angular.module('cartangularPublicShoppingApp', [
'ngRoute',
'CategoriesController',
'CategoryServices',
'CategoryNavigationServices',
'MenuModule'
]);
cartangularPublicShoppingApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/categories/:categoryId', {
templateUrl: 'partials/public/categories.html',
controller: 'CategoriesController'
})
}]
);





This is the main controller for the view (categories.html) that will be used to show off our custom directive. I created a test dataset called treeFamily that I will use to test the directive in this controller



var categoriesControllers = angular.module('CategoriesController', []);

categoriesControllers.controller('CategoriesController', ['$scope', '$routeParams' , '$location', 'CategoryService',
function($scope, $routeParams, $location, CategoryService) {

$scope.treeFamily = {
name : Clothes,
categoryId : 4,
children: [{
name : Clothes,
categoryId : 3,
children: [{
name : Men's Clothes,
categoryId : 2,
children: []
},{
name : Jackets,
categoryId : 1,
children: [
{
name : Light Jackets,
categoryId : 4,
children: [{
name : Natural Material,
children: []
}
]
},{
name : Heavy Jackets,
categoryId : 3,
children: []
}]
}, {
name: Pants,
categoryId : 4,
children: []
}]
}]
}





Here is the directive that we will use to recursively traverse our dataset.



angular.module('MenuModule', [])
.directive(tree, function(RecursionHelper) {
return {
restrict: E,
scope: {
family: '=',
'product': '&products'
},

templateUrl: './partials/public/family.html',
compile: function(element) {
return RecursionHelper.compile(element);
}
};
})





This is a compiling service that I found someone demonstrating online.
I decided to use it, as it keeps our code neat and clean.



var categoryNavigationServices = angular.module('CategoryNavigationServices', []);
categoryNavigationServices.factory('RecursionHelper', ['$compile', function($compile){
var RecursionHelper = {
compile: function(element){
var contents = element.contents().remove();
var compiledContents;
return function(scope, element){
if(!compiledContents){
compiledContents = $compile(contents);
}
compiledContents(scope, function(clone){
element.append(clone);
});
};
}
};

return RecursionHelper;
}]);





This is the html fragment for our directive. Note how we are calling the directive from within the directive.



<a href=javascript:void(0); name=categoryId ng-click=product(family.categoryId)>{{ family.name }}</a>
<ul>
<li ng-repeat=child in family.children>
<tree family=child products=products(child.categoryId)></tree>
</li>
</ul>





Here is part of my categories.html page which is the main view from my controller.



    <ul>
<li ng-repeat=object in treeFamily.children>
<a href=javascript:void(0); name=categoryId ng-click=products(object.categoryId)>{{object.name}}</a>
<ul>
<li ng-repeat=child in object.children>
<tree family=child products=products(child.categoryId)></tree>

</li>
</ul>
</li>
</ul>





The main problem I was having after i got the recursive directives working was that my ng-click that I added to the directive's html was not responding when clicked.
This was because the scope on the directive was an isolated scope.



In order to access the main controller's method, you have to bind the directive's method to the controller's method.
in order to do this you have to add the controller's function you want to bind to within the tag its'self.
ie:



<tree family=child products=products(child.categoryId)>


and the directive's isolated scope references this
ie:



scope: {
family: '=',
'product': '&products'
},


The a href inside the directive's html is as such:



<a href=javascript:void(0); name=categoryId ng-click=product(family.categoryId)>{{ family.name }}</a>


note that we reference the directive's function product, and not products, which is the name of the method on the controller that we wanted access to.


[#74247] Friday, November 15, 2013, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
alvin

Total Points: 55
Total Questions: 101
Total Answers: 109

Location: Sudan
Member since Tue, Aug 3, 2021
3 Years ago
;