How to access parent scope in directive on nested ng-repeat - angularjs

Simple question but i unable to find why in this template, the format-property directive can not access to device?
<table>
<tr ng-repeat="device in devices">
<format-property ng-repeat="property in properties"></format-property>
</tr>
</table>
althought with this template it works:
<table>
<tr ng-repeat="device in devices">
<td ng-repeat="property in properties">
<format-property></format-property>
</td>
</tr>
</table>
I tried scope.device and scope.$parent.device without success.
Here my demo
Edit
I can access to property but not to device. Unlike this question, i have a nested ng-repeat
Here a new demo with an isolated scope

see plunker
I think you must add td inside tr or you can use div.
Also you can check this link for more details.

Related

Ng-repeat - What is the right syntax to send the user to its dynamic id?

So, in my object index I'm working inside a ng-repeat.
Now, when I click on an object, it should go to its matching id.
How would I do this with Angular?
I got something like this now:
<tr ng-repeat="dossier in dossiers">
<td>
#{{dossier.license_plate}}
</td>
</tr>
Why don't you try ngHref directive
<tr ng-repeat="dossier in dossiers">
<td>
<a ng-href="/dossiers/{{dossier.id}}">#{{dossier.license_plate}}</a>
</td>
<a ng-href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
https://docs.angularjs.org/api/ng/directive/ngHref

Angular.js: How to use ng-model outside its scope

I have searched a lot for this and couldn't get an appropriate answer. I am sorry if i am asking this question again. I am new to Angular.js
my code:
<table>
<tr>
<th ng-repeat="x in setno" ng-init="parentset=$index">SET {{ x.alpha }}</th>
</tr>
<tr ng-repeat="(parentset,ques) in selected">
<td ng-repeat="x in setno">
<select ng-model="ques" ng-options="y.name for y in topics"></select>{{ques.qid}}
</td>
<td>{{$parent.ques.qid}}hi</td>
</tr>
<tr>
<td ng-repeat="x in setno">
<button ng-click="addques($index,ques.qid)" ng-model="ques.quid">add{{$parent.ques.qid}}</button>
</td>
</tr>
</table>
The ques ng-model is working fine just after the select tag but inside td tag only. How can i use it outside that particular tag.
ie, here:
<td>{{$parent.ques.qid}}hi</td>
and here:
<button ng-click="addques($index,ques.qid)" ng-model="ques.quid">add{{$parent.ques.qid}}</button>?
I have tried $parent and without it, but its not working.
Where am i going wrong?
The select tag has his own scope so you have to extend an object in the parent scope if you want to use "ques" out of the select tag.
To do so, create an object (a $scope variable) in the parent :
$scope.test;
And extends it in the select (the child scope) :
ng.model = "test.ques";
Then you can access "ques" out of the select tag.

ng-repeat over a div not working

I have used ng-repeat numerous times already in the past, but for some reason I cannot yet understand why it is not on the following situation:
I have an array of objects called registers which I am referencing on the ng-repeat but nothing happens.
I know the array is populated because I have seen it on numerous console.log and because it works if I move the ng-repeat over to the <tbody>
<div ng-repeat = "r in registers">
<!-- START HEADER -->
<tbody class="js-table-sections-header">
<tr>
<td class="text-center">
<i class="fa fa-angle-right"></i>
</td>
<td class="font-w600">Denise Watson</td>
</tr>
</tbody> <!-- END HEADER -->
<tbody>
<tr>
<td class="text-center"></td>
<td>
<!-- Summernote Container -->
<div class="js-summernote-air">
<p>End of air-mode area!</p>
</div>
</td>
</tr>
</tbody>
<!-- END TABLE -->
</div>
I was hoping someone could tell me if there is something I may be ignoring.
Thanks in advance.
I think I just ran into this same problem. It stems from <div> not being a valid elment within a <table>.
I'm guessing that since you have <tbody> there, that there is a <table> tag that was left out of your snippet. <div>s aren't allowed in a table, so the browser moves it before the table. In my situation, doing this, causes the angular scope to change so that there was nothing to iterate over. You can verify this by using the developer tools of your browser.
So, my guess is that you probably want to move the ng-repeat onto the <tbody> or <table> tag.
If you want to use ng-repeat in "div" tag means use "span"
inside div tag. instead of using "table" and its sub attributes..
else use your ng-repeat inside "table" or "thead" or "tr" also
it will iterate rows ...
than only ng-repeat will works.

Evaluating expression inside angular directive

I want my table to conditionally render its row based on whether the value is null or not. The rows have different custom entries and labels, that's why I can't just use ng-repeat. Here's the code:
<table>
<thead>
</thead>
<tbody>
<tr ng-show = "{{data.entry_1}} !== null">
<td>Custom Label 1</td>
<td>{{data.entry_1}}</td>
</tr>
<tr ng-show = "{{data.entry_2}} !== null">
<td>Custom Label 2</td>
<td>{{data.entry_2}}</td>
</tr>
.
.
.
<tr ng-show = "{{data.entry_n}} !== null">
<td>Custom Label n</td>
<td>{{data.entry_n}}</td>
</tr>
</tbody>
</table>
However, it seems that this way is not right. It's either javascript (compiler) is complaining at {{}} in the ng-show or at '!== null' or maybe both. How to evaluate an angular expression (in {{}}) inside an ng- directive?
I know that I could also evaluate this instead in the js file, but since I don't want to add further scope variables (to make my code cleaner), I chose to evaluate if it is null in the ng-show directive. Could someone tell me how to do it?
Thanks.
You were close. The curly braces are only needed to echo/print/render the value of the variable. In an expression you should never use the curly braces.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app ng-init="data = {entry_1: 'notnull', entry_2: null, entry_n: 'againNotNull'}">
<thead>
</thead>
<tbody>
<tr ng-show="data.entry_1">
<td>Custom Label 1</td>
<td>{{data.entry_1}}</td>
</tr>
<tr ng-show="data.entry_2">
<td>Custom Label 2</td>
<td>{{data.entry_2}}</td>
</tr>
.
.
.
<tr ng-show="data.entry_n">
<td>Custom Label n</td>
<td>{{data.entry_n}}</td>
</tr>
<tr ng-show="data.device">
<td>Custom Device</td>
<td>{{data.device}}</td>
</tr>
</tbody>
</table>
Use $compile service in the context of the scope inside your directive.
See https://docs.angularjs.org/api/ng/service/$compile
Edit: I agree with Martin's answer.

angularJS - Repeating tr's in a table, but dynamically adding more rows while looping

Since examples always tell more then just words here is what I would like to do in another language
<tr>
<c:forEach items="${items}" var="item">
<td>...</td>
<td>...</td>
<td>...</td>
<c:if test="${item.showWarning}">
</tr><tr><td colspan="3">${item.warning}</td>
</c:if>
</tr>
So this will loop over a set of items and show some properties of these items. If there is a warning, a new row will be added underneath the current row in which the warning will be shown. However, how can I do this in angularJs? If I put a ng-repeat on the tr, it will stop at the first end tag of tr. I have read on some other threads that this is not very easily done, but how can it be done? And yes, I really do want to use a table. Here is my contrived example with angularjs which is obviously not working as I would like it to. Any pointers how this can be done?
JSBin example with tr-ng-repeat
Currently (1.0.7/1.1.5) you can't output data outside the ng-repeat, but version 1.2(see youtube video AngularJS 1.2 and Beyond at 17:30) will bring the following syntax(adapted to your example):
<tr ng-repeat-start="item in items">
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<tr ng-repeat-end ng-show="item.showWarning">
<td colspan="3">{{item.warning}}</td>
</tr>
The idea is that whatever is between -start and -end will be repeated including the -end element.
One solution that I can think of is having multiple tbody tags within the same table. Here is a discussion on the use of multiple tbody tags within the same table.
So, for your issue, you could have the following setup:
<table ng-controller="ItemController">
<thead>
<th>Name</th>
<th>Description</th>
<th>warning?</th>
</thead>
<tbody ng-repeat="item in items">
<tr>
<td>{{item.name}}</td>
<td>{{item.description}}</td>
<td>{{item.warning}}</td>
</tr>
<tr ng-show="item.warning">
<td colspan="3" style="text-align: center">Warning !!!</td>
</tr>
</tbody>
</table>
Repeat the table body as many times as there are entries for the table and within it have two rows - one to actually display the row entry and one to be displayed conditionally.
You can repeat over the tbody
<tbody ng-repeat="item in items">
<tr>
<td>{{item.name}}</td>
<td>{{item.description}}</td>
<td>{{item.warning}}</td>
</tr>
<tr ng-show="item.warning">
<td colspan="3">Warning !!!</td>
</tr>
</tbody>
Also you do not need to wrap the ng-show expression in {{}}, you can just use item.warning

Resources