Zenwalker Zenwalker - 5 months ago 7
AngularJS Question

Insert html under specific <li> element ng-repeat - AngularJS

I have started to learn AngularJS from pluralsight. Based on the tutorial, i managed to write a Github user listing APP using routing and basic directives.

<div ng-controller="RepositoryController">
<h3 ng-hide="!repoDetails">Repository owned:</h3>

<div ng-repeat="repo in repoDetails">

<img ng-src="{{contributorsList == undefined && './Images/collapsed.jpg' || './Images/expanded.jpg'}}" ng-click="listContributors(repo.name)" />{{repo.name}}
{{contributorsList == undefined}}
<div id={{repo.name}} style="padding-left: 55px">
</div>
</div>




Please look http://plnkr.co/edit/ztArGBEmPeoNMk5khkDi

As you can see from the app, the first main page lists out the users of Github and upon clicking their profile URL in the table, it details out the user info and bottom of it, it lists down the repositories owned.

You can click on the each repository arrow icon, wherein it expands to show the contributors to that repository.

As you can see, repositoryController.js has a code which inserts a UL-LI tags with ng-repeat directive into the html/view. Reason is, that the template is same for all the repository-contributors listing segment.

Problem:


  1. Upon expanding one arrow icon under Repository list, all others li element contents/childrens as well gets effected in showing the same content. So how to inject for only particular li element? and not disturb others.

  2. The arrow icons as well gets effected if one element clicked, the rest changes, because ng-src has a conditional check. So how to change the icon for particular li element upon user click, yet not sending every time from controller.



Any other code improvements and suggests are welcome.

Kindly provide your detailed explanation, suggestions to the problem. Helps me to understand better and learn.

Thank you

rob rob
Answer

If you ever find yourself needing to use $compile or do a lot of DOM manipulation in an Angular app it is a sign you have taken a wrong turn. Here is an example of how you can do this without any manual DOM manipulation or HTML string parsing.

http://plnkr.co/edit/DHelPTU7gqPPEQzo41fo?p=preview

HTML

<div ng-repeat="repo in repoDetails">    

    <img 
      ng-show="!repo.showContributors"
      src="http://cdn.shopify.com/s/files/1/0434/3957/t/32/assets/icon-arrow-right-small.png" 
      ng-click="listContributors(repo)" />
    <img 
      ng-show="repo.showContributors"
      src="http://cdn.shopify.com/s/files/1/0434/3957/t/26/assets/icon-arrow-down-small.png" 
      ng-click="repo.showContributors = false" />
    {{repo.name}}
    {{contributorsList == undefined}}
    <div id={{repo.name}} style="padding-left: 55px">
      <ul ng-if="repo.showContributors">
        <li ng-repeat='contributor in repo.contributors'>{{contributor.login}}</li>
      </ul>
    </div>
</div>

JS

$scope.listContributors = function (repo) {
  repo.showContributors = true;
  loadContributors(repo.name).then(function(response) {
    repo.contributors = response.data;
  });
}

var loadContributors = function (repoName) {
    return $http.get("https://api.github.com/repos/" + $routeParams.username + "/" + repoName + "/contributors");
};