2

I am doing a template for every content of and because I have much data to show but all in the same structure.

Here the index.html

<div ng-model="methods" 
 ng-include="'templateMethod.html'" 
 ng-repeat = "method in methods">

here the script.js:

function Ctrl($scope) {
$scope.methods =
[ { name: 'method1',
    description: 'bla bla bla',
    benefits: 'benefits of method1',
    bestPractices : 'bestPractices',
    example: 'example'},

 { name: 'method2',
    description: 'bla bla bla',
    benefits: 'benefits of method2',
    bestPractices : 'bestPractices',
    example: 'example'} ];
}

and here the templateMethod.html:

<table>
 <tr>
   <td>
     <div ng-show="toShow=='{{method.name}}Field'">
     <h3>{{mmethodethod.name}}</h3>
     <p>    
       <strong>Description</strong>
       {{method.description}}
     </p>
     <p>    
       <strong>Benefits</strong>
       {{method.benefits}}
     </p>
     <p>
       <strong>Best practices</strong>
       {{method.bestPractices}}
     </p>
      <p>   
        <strong>Examples</strong>
        {{method.example}}
      </p>
    </div>
    </td>
    <td class = "sidebar">
      <ul>
         <li><a ng-click="toShow='{{method.name}}Field'" class="{{method.name}} buttons">{{method.name}}</a></li>   
      </ul>             
    </td>
  </tr>
</table>

It works! But: if I click the first button and then the second one, the content of the first button do not disappear, it appears under the content of the first button... Problem with the repetition?

Thanks

1
  • try ng-click="$parent.toShow='{{method.name}}Field'" ... a live demo in plunker or jsfiddle always helps. Description isn't 100% clear what issue is Commented Oct 27, 2013 at 18:12

3 Answers 3

1

Each element of an ng-repeat has its own scope, inheriting from the outer (controller) scope.

You should store the object to show in an object of the controller scope. For example: methods

<div ng-show="methods.toShow=='{{method.name}}Field'">
...
<a ng-click="methods.toShow='{{method.name}}Field'"
Sign up to request clarification or add additional context in comments.

Comments

1

Basically what JB Nizet said, here is a working plunker. The problem is that ng-include and ng-repeat create their own scopes. Child scopes have read only access to their parent scope's properties, thus you need an extra object reference to get both read and write access between scopes.

Javascript:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.state = { toShow: false };
  $scope.methods = [{
      name: 'method1',
      description: 'bla bla bla',
      benefits: 'benefits of method1',
      bestPractices: 'bestPractices',
      example: 'example'
    },

    {
      name: 'method2',
      description: 'bla bla bla',
      benefits: 'benefits of method2',
      bestPractices: 'bestPractices',
      example: 'example'
    }
  ];
});

HTML:

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js" data-semver="1.1.5"></script>
    <script src="app.js"></script>
    <script type="text/ng-template" id="templateMethod.html">
      <table>
       <tr>
         <td>
           <div ng-show="state.toShow == '{{method.name}}Field'">
           <h3>{{mmethodethod.name}}</h3>
           <p>    
             <strong>Description</strong>
             {{method.description}}
           </p>
           <p>    
             <strong>Benefits</strong>
             {{method.benefits}}
           </p>
           <p>
             <strong>Best practices</strong>
             {{method.bestPractices}}
           </p>
            <p>   
              <strong>Examples</strong>
              {{method.example}}
            </p>
          </div>
          </td>
          <td class = "sidebar">
            <ul>
               <li><a ng-click="state.toShow = '{{method.name}}Field'" class="{{method.name}} buttons">{{method.name}}</a></li>   
            </ul>             
          </td>
        </tr>
      </table>
    </script>
  </head>

  <body ng-controller="MainCtrl">
    <div ng-model="methods" 
 ng-include="'templateMethod.html'" 
 ng-repeat = "method in methods">
  </body>

</html>

Comments

1

The issue is actually related to the fact that for each ng-repeat Angular creates a new scope, so you need to have something in a parent scope, ie: a Controller where you can use to reference the visible status of each method, something like this:

http://jsfiddle.net/strokov/FEgK3/1/

Basically I set the ng-show to a property of the method object:

 <div ng-show="method.show">

And on the click method, I call a function on the Scope called show(method) which is going to take care of setting the method.show property on all methods so basically we are hidden all and then show the clicked one like this:

$scope.show = function(method) {
    angular.forEach($scope.methods, function(method){
       method.show = 0;
    });
    method.show = 1;
};

You will notice that with this css style how to see each different angular scope represented in the HTML:

.ng-scope { border: 1px dashed red; margin: 5px; }

1 Comment

Thank you all, now it works! I simply add what Nizet said, but thank you all :-)

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.