Angular 如果我添加 ng-if,ng-show 将不起作用
Angular ng-show doesn't work if I add ng-if
我正在使用 Angular 开发一个网络应用程序,其中包含一个 table 和一个可折叠的 tr
。但是当我添加一些 ng-if 条件时(如果数组中有/没有数据),ng-show 停止工作。
这是没有 ng-if 条件的工作代码:https://plnkr.co/edit/UPFF1RboN22RAVM8r18i?p=preview
<thead>
<tr role="row">
<th class="details-control sorting_disabled" rowspan="1" colspan="1" aria-label="" style="width: 26px;">
<th class="sorting_asc" tabindex="0" aria-controls="example" rowspan="1" colspan="1" aria-label="Projects: activate to sort column descending" aria-sort="ascending" style="width: 306px;">Foods</th>
<th class="sorting" tabindex="0" aria-controls="example" rowspan="1" colspan="1" aria-label=" EST: activate to sort column ascending" style="width: 84px;"><i class="fa fa-fw fa-user text-muted hidden-md hidden-sm hidden-xs"></i> Type</th>
<th class="sorting" tabindex="0" aria-controls="example" rowspan="1" colspan="1" aria-label="Contacts: activate to sort column ascending" style="width: 107px;">Count</th>
</tr>
</thead>
<tbody ng-repeat="data in allData" >
<tr>
<td>
<div class="cursor-pointer" ng-click="rows = !rows">
<!-- <span class="fa" ng-class="{'fa-caret-down': rows, 'fa-caret-right': !rows}"></span> -->
<p>open</p>
</div>
</td>
<td>{{data.foodName}}</td>
<td></td>
<td>{{data.totalCount}}</td>
</tr>
<tr ng-repeat="a in data.avaiable" ng-show="rows" ng-if="allData && allData.length > 0">
<td></td>
<td></td>
<td>{{a.foodType}}</td>
<td>{{a.foodCount}}</td>
</tr>
这是带有 ng-if 条件的无效代码。如果您在 plk https://plnkr.co/edit/IvlIXIfWpogNi5VXo2Eh?p=preview 看到,您会注意到这些行没有显示。为什么?
它不起作用的原因是 ng-if 创建了一个新的子范围,从而打破了原型范围继承。
必须阅读才能更好地理解这个问题:
- Angularjs ng-model doesn't work inside ng-if.
- What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
作为一个好的经验法则,请始终使用 controller as syntax. Here 这就是你应该使用它的原因。
一个 快速修复 你会从另一个对象访问 rows
属性 像这样:ng-show="container.rows"
- 这样你不会破坏原型范围继承。查看工作示例 here.
如果您需要检查 allData
中是否有数据并且基于 allData
想要使用 ng-repeat
然后在同一元素中使用 ng-if
条件
<tbody ng-if="allData && allData.length > 0" ng-repeat="data in allData" >
而不是嵌套元素<tr ng-if="allData && allData.length > 0">
最好使用 data.rows
而不是 rows
在 ng-click
中设置并在 ng-show
中显示特定数据行。像:ng-click="data.rows = !data.rows"
和 ng-show="data.rows"
总的解决方案可以是:
<table>
<thead>
<tr></tr>
</thead>
<tbody ng-if="allData && allData.length > 0" ng-repeat="data in allData" >
<tr >
<td>
<div class="cursor-pointer" ng-click="data.rows = !data.rows">
<p>open</p>
</div>
</td>
<td>{{data.foodName}}</td>
.....
</tr>
<tr ng-repeat="a in data.avaiable" ng-show="data.rows" ng-if="data.avaiable && data.avaiable.length > 0">
....
<td>{{a.foodCount}}</td>
</tr>
</tbody>
<tbody ng-if="!allData || allData.length == 0">
<tr class="yourClass">
<td colspan="3">
<span translate="generic.NO_DATA_FOUND"></span>
</td>
</tr>
</tbody>
</table>
Cosmin 是对的。
ng-if 创建一个新的 child 作用域。
您必须使用 $parent
才能使用您在 ng-if
中使用的 parent 变量
把你ng-click改成:
ng-click="$parent.rows = !rows"
工作Plunker
要显示未找到数据 使用您的其他 body table
<tbody ng-repeat="data in allData" >
<tr ng-if="allData && allData.length > 0">
<td>
<div class="cursor-pointer" ng-click="$parent.rows = !rows">
<!-- <span class="fa" ng-class="{'fa-caret-down': rows, 'fa-caret-right': !rows}"></span> -->
<p>open</p>
</div>
</td>
<td>{{data.foodName}}</td>
<td></td>
<td>{{data.totalCount}}</td>
</tr>
<tr ng-repeat="a in data.avaiable" ng-show="rows" ng-if="allData && allData.length > 0">
<td></td>
<td></td>
<td>{{a.foodType}}</td>
<td>{{a.foodCount}}</td>
</tr>
</tbody>
<!-- If there are no data -->
<tbody ng-if="allData && (allData == null || allData.length == 0)">
<tr>
<td colspan="3"><span translate="generic.NO_DATA_FOUND">NO DATA FOUND</span></td>
</tr>
</tbody>
根据你的需求理解如果你只是替换代码
ng-click="rows = !rows"
与 ng-click="data.rows = !data.rows"
和
ng-show="rows"
与 ng-show="data.rows"
一定有用
我正在使用 Angular 开发一个网络应用程序,其中包含一个 table 和一个可折叠的 tr
。但是当我添加一些 ng-if 条件时(如果数组中有/没有数据),ng-show 停止工作。
这是没有 ng-if 条件的工作代码:https://plnkr.co/edit/UPFF1RboN22RAVM8r18i?p=preview
<thead>
<tr role="row">
<th class="details-control sorting_disabled" rowspan="1" colspan="1" aria-label="" style="width: 26px;">
<th class="sorting_asc" tabindex="0" aria-controls="example" rowspan="1" colspan="1" aria-label="Projects: activate to sort column descending" aria-sort="ascending" style="width: 306px;">Foods</th>
<th class="sorting" tabindex="0" aria-controls="example" rowspan="1" colspan="1" aria-label=" EST: activate to sort column ascending" style="width: 84px;"><i class="fa fa-fw fa-user text-muted hidden-md hidden-sm hidden-xs"></i> Type</th>
<th class="sorting" tabindex="0" aria-controls="example" rowspan="1" colspan="1" aria-label="Contacts: activate to sort column ascending" style="width: 107px;">Count</th>
</tr>
</thead>
<tbody ng-repeat="data in allData" >
<tr>
<td>
<div class="cursor-pointer" ng-click="rows = !rows">
<!-- <span class="fa" ng-class="{'fa-caret-down': rows, 'fa-caret-right': !rows}"></span> -->
<p>open</p>
</div>
</td>
<td>{{data.foodName}}</td>
<td></td>
<td>{{data.totalCount}}</td>
</tr>
<tr ng-repeat="a in data.avaiable" ng-show="rows" ng-if="allData && allData.length > 0">
<td></td>
<td></td>
<td>{{a.foodType}}</td>
<td>{{a.foodCount}}</td>
</tr>
这是带有 ng-if 条件的无效代码。如果您在 plk https://plnkr.co/edit/IvlIXIfWpogNi5VXo2Eh?p=preview 看到,您会注意到这些行没有显示。为什么?
它不起作用的原因是 ng-if 创建了一个新的子范围,从而打破了原型范围继承。
必须阅读才能更好地理解这个问题:
- Angularjs ng-model doesn't work inside ng-if.
- What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
作为一个好的经验法则,请始终使用 controller as syntax. Here 这就是你应该使用它的原因。
一个 快速修复 你会从另一个对象访问 rows
属性 像这样:ng-show="container.rows"
- 这样你不会破坏原型范围继承。查看工作示例 here.
如果您需要检查 allData
中是否有数据并且基于 allData
想要使用 ng-repeat
然后在同一元素中使用 ng-if
条件
<tbody ng-if="allData && allData.length > 0" ng-repeat="data in allData" >
而不是嵌套元素<tr ng-if="allData && allData.length > 0">
最好使用 data.rows
而不是 rows
在 ng-click
中设置并在 ng-show
中显示特定数据行。像:ng-click="data.rows = !data.rows"
和 ng-show="data.rows"
总的解决方案可以是:
<table>
<thead>
<tr></tr>
</thead>
<tbody ng-if="allData && allData.length > 0" ng-repeat="data in allData" >
<tr >
<td>
<div class="cursor-pointer" ng-click="data.rows = !data.rows">
<p>open</p>
</div>
</td>
<td>{{data.foodName}}</td>
.....
</tr>
<tr ng-repeat="a in data.avaiable" ng-show="data.rows" ng-if="data.avaiable && data.avaiable.length > 0">
....
<td>{{a.foodCount}}</td>
</tr>
</tbody>
<tbody ng-if="!allData || allData.length == 0">
<tr class="yourClass">
<td colspan="3">
<span translate="generic.NO_DATA_FOUND"></span>
</td>
</tr>
</tbody>
</table>
Cosmin 是对的。
ng-if 创建一个新的 child 作用域。
您必须使用 $parent
才能使用您在 ng-if
把你ng-click改成:
ng-click="$parent.rows = !rows"
工作Plunker
要显示未找到数据 使用您的其他 body table
<tbody ng-repeat="data in allData" >
<tr ng-if="allData && allData.length > 0">
<td>
<div class="cursor-pointer" ng-click="$parent.rows = !rows">
<!-- <span class="fa" ng-class="{'fa-caret-down': rows, 'fa-caret-right': !rows}"></span> -->
<p>open</p>
</div>
</td>
<td>{{data.foodName}}</td>
<td></td>
<td>{{data.totalCount}}</td>
</tr>
<tr ng-repeat="a in data.avaiable" ng-show="rows" ng-if="allData && allData.length > 0">
<td></td>
<td></td>
<td>{{a.foodType}}</td>
<td>{{a.foodCount}}</td>
</tr>
</tbody>
<!-- If there are no data -->
<tbody ng-if="allData && (allData == null || allData.length == 0)">
<tr>
<td colspan="3"><span translate="generic.NO_DATA_FOUND">NO DATA FOUND</span></td>
</tr>
</tbody>
根据你的需求理解如果你只是替换代码
ng-click="rows = !rows"
与 ng-click="data.rows = !data.rows"
和
ng-show="rows"
与 ng-show="data.rows"
一定有用