Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

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

share|improve this question
up vote 1 down vote accepted

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");
};
share|improve this answer
    
Thank you very much. As i read, i was aware to not do DOM manipulations in Angular, as its against the philosophy. But the solution was beyond my knowledge, hence had to try inserting the HTML. AFAIK, DOM manipulations are to be done by only directives. So next ill learn how to build them. I shall keep your pointers noted. – Zenwalker Jul 5 at 18:47
    
even ng-include is not good to use in a controller where in i am inserting an html template? Its kind of modifying the html DOM right? Thanks – Zenwalker Jul 5 at 19:28
1  
I usually avoid using ng-include. If the html is only used in one place I would put it directly in the view. If it is used in multiple places I would create a directive with an isolated scope. Angular has a lot of concepts that overlap and are somewhat redundant so I try to work with a minimal subset of them. – rob Jul 5 at 19:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.