7

Creating my first AngularJS app.

A ng-repeat:er loads titles. Each title is clickable. When clicking a title, an ajax-call is getting more JSON data. I need to add this data below the clicked title.

The normal way, I would create the HTML as a string and append it to the source code. But since I'm using AngularJS, there should be a way to create a partial view with the HTML and another ng-repeat in it.

How can this be done?

4
  • 2
    That sounds like a good match for implementation of routing in your page. Take a look at this part of Angular's official tutorial: docs.angularjs.org/tutorial/step_07 and this documentation entry: docs.angularjs.org/api/ng.directive:ngView Commented May 16, 2013 at 14:08
  • Yes, this seem to be the best way. I was first thinking about not using routes, but this will do. One thing I don't understand is: how do you "append" a partial view into another partial view? Commented May 16, 2013 at 15:24
  • 1
    Take a look at ng-include directive: docs.angularjs.org/api/ng.directive:ngInclude. With it you can include partials that can also have ng-include in them — having partials in partials and so on. And you can dynamically change the partial's source (by setting the url to some object reference rather than string literal — it's shown in the example of the documentation entry I've included). Commented May 16, 2013 at 15:27
  • Maybe have the view in a directive and then append the html of the directive as an element when you need it. That is if you truly do not want to preload the html and use ng-show/ng-hide. Commented Sep 8, 2015 at 20:03

2 Answers 2

2

I would use a directive as per @Nicolas suggestion. Combining this with what @Andrew suggested you could do something like this.

Controller:

.controller('MainCtrl', function ($scope, $http) {
    $scope.items = [
        {id: 'a', subItems: []},
        {id: 'b', subItems: []}
    ];

    $scope.getSubItems = function(id) {
        $http.get('/sub-items/' + id)
            .then(function() {
                $scope.items.subItems = $scope.items.subItems.push(response.data);
            });
    }
});

View:

<div ng-repeat="item in items">
  <a ng-click="getSubItems(item)">{{item.id}}</a>
  <list sub-items="item.subItems"></list>
</div>

Directive:

.directive('list', function() {
    return {
        restrict: 'E',
        scope: {
          subItems: '=subItems'
        },
        template: '<ul>' +
            '<li ng-repeat="subItem in subItems">{{subItem.id}}</li>' +
          '</ul>'
    };
});
Sign up to request clarification or add additional context in comments.

Comments

0

Here's a small example: Your JSON is structured simply, with subItems array in each item's json object.

JS:

function MyCtrl($scope, $http) {
  $scope.items = [ {id: 'a', subItems: []}, {id: 'b', subItems: []} ];

  $scope.getSubItems = function(item) {
    $http.get('/sub-items/' + item.id).then(function(response) {
      //Append the response to the current list of subitems 
      //(incase some exist already)
      item.subItems = item.subItems.concat(repsonse.data);
    });
  };
}

HTML:

<div ng-repeat="item in items">

  <a ng-click="getSubItems(item)">{{item.id}}</div>
  <div ng-show="item.subItems.length">
    <h4>SubItems:</h4>
    <ul>
      <li ng-repeat="subItem in item.subItems">{{subItem}}</li>
    </ul>
  </div>

</div>

2 Comments

Thanks, this seems like a good solution, but I would prefer to use partial views to reduce the amount of generated HTML, also better structure in the app. This might come handy some other time though.
I would use a directive to do that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.