-1

Ok, I'm trying to create a categories browser, something like eBay, using AngularJS.

I have the root categories:

<div id='root'>
    <ul>
        <li data-ng-repeat='category in categories'>
            <a href='#'
                data-ng-bind='category.Name'  
                data-ng-click='browseCategories(category, "children-1")'>
            </a>
         </li>
    </ul>
</div>

<div id='children-1'>
</div>

<div id='children-2'>
</div>

The purpose of the browseCategories method is to fill children-1 div with the children of the selected category.

$scope.browseCategories = function(category, moveTo) {

    //looping in order to create a new <ul> of children categories.
    var html = "<ul class='unstyled'>";
    for (var I = 0; I < category.Children.length; ++I) {
        var category = category.Children[I];
        html += "<li><a href='#' data-ng-click='browseCategories(" + 
            category + ", 'children-1')'>" + category.Name + "</a>";
    }
    html += "</ul>";

    var elMoveTo = angular.element(moveTo);
    $(elMoveTo).html(html);
}

Well, the new <ul> is properly attached to the element, but the browseCategories method stops to work. What's happening?

Thanks for all

Kiwanax
  • 1,265
  • 1
  • 22
  • 41
  • You are trying do an recursive list? – Callebe Aug 15 '14 at 00:46
  • You're going to need a $scope.$apply() if you are going to add HTML like that. Consider creating a directive. – TrazeK Aug 15 '14 at 00:49
  • @TrazeK, even using a directive, the `data-ng-click` attribute doesn't work. When I try to inspect the element, it shows me `browseCategories([Object] object, 'children-1')` and the `click` method is not fired. – Kiwanax Aug 15 '14 at 03:16
  • I see. Until I get a chance to work on this, give this a look as I think it's what you will need to do in your directive: https://docs.angularjs.org/api/ng/service/$compile I don't wanna post an "answer" until I have a chance to test etc. The idea is you need to "compile" your HTML so Angular can recognize it. – TrazeK Aug 15 '14 at 04:07

3 Answers3

0

try this recursive ngRepeat

How can I make recursive templates in AngularJS when using nested objects?

your browseCategories function could just load the child list when it is clicked.

Community
  • 1
  • 1
Callebe
  • 1,087
  • 7
  • 18
  • Thanks, @Callebe. I can use this recursive engine with templates, but the idea is just load a new piece of categories when the user selects any of the previous list, got it? – Kiwanax Aug 15 '14 at 03:10
0

In your for loop, you created var category which is already a variable

$scope.browseCategories = function(category, moveTo) {

    //looping in order to create a new <ul> of children categories.
    var html = "<ul class='unstyled'>";
    for (var I = 0; I < category.Children.length; ++I) {
        var category = category.Children[I];
            ^^^^^^^^

Try renaming that and see.

This might do whatever you are trying to achieve. Hope that helps.

But when you're doing it in angular, the best practice is to avoid any other libraries like jQuery and try to achieve it in the angular way. Angular is so powerful.

See this SO post: "Thinking in AngularJS" if I have a jQuery background?

Community
  • 1
  • 1
Raghavendra
  • 5,281
  • 4
  • 36
  • 51
0

As I mentioned in my comment, you need to use the $compile service to "compile" your raw HTML into something Angular understands. I made a Plunker illustrating this. I made some changes to the code and some assumptions on what your $scope.categories array looks like. Hopefully I am not way off basis.

link: function(scope, element) {

  scope.browseCategories = function(category, moveTo) {

    console.log("category", category);
    scope.c = category;

    //looping in order to create a new <ul> of children categories.
    var html = "<ul class='unstyled'>";
    for (var I = 0; I < category.Children.length; ++I) {
      var c = category.Children[I];
      html += "<li><a href='#' data-ng-click=\"browseCategories(c, 'children-3')\">" + category.Name + "</a>";
    }
    html += "</ul>";

    var link = $compile(html);
    var content = link(scope);
    $("#" + moveTo).html(content);
  }
},

So before using the $compile service, you'd need to bind the category array to scope so Angular knows what is being passed into the browseCategories after being drawn to the screen again via the $("#" + moveTo).html(content);.

 html += "<li><a href='#' data-ng-click=\"browseCategories(c, 'children-3')\">" + category.Name + "</a>"; 

notice the variable c is being passed in

In general as @Raghav mentioned, you want to avoid techniques like this, not relying on third party libraries and using the $compile service to handle raw HTML.

Hopefully this helps you achieve whatever goal you are striving for.

Edit: I updated my Plunker to have the correct id values for the children div to better illustrate the functionality

TrazeK
  • 838
  • 1
  • 8
  • 18
  • Thanks, @TrazeK, the `$compiler` directive works perfectly. I write the code using the angularJS syntax and attributes, compile it to the current scope and works like a charm. Thanks! – Kiwanax Aug 15 '14 at 17:37