我有一个指令,负责确认过程的功能(见图片)。它按预期工作,除非单击“提交”按钮后,将显示所有tr的检查图标。但是,它只应显示在已经确认的tr上。
不幸的是,我无法创建一个有效的Plunker,并希望这些图片足以让您理解我的问题。
我做错了什么?
角指令:
.directive('confirm', function($timeout) {
return {
restrict: 'A',
scope: true, // isolate the scope to trigger target individually
link: function(scope, element) {
$timeout(function() {
var barIcon = angular.element(element[0].querySelector('.config-menu-bars'));
var banIcon = angular.element(element[0].querySelector('.config-menu-ban'));
var checkIcon = angular.element(element[0].querySelector('.config-menu-checked'));
var confirmLink = angular.element(element[0].querySelector('.confirm'));
var textArea = angular.element(element[0].querySelector('.confirmation-note'));
// These elements are outside the scope of the directive
var confirmBox = angular.element('.accept-terminplanung');
var submitButton = angular.element('.submit-appointment');
var confirmCheckbox = angular.element('.appointment');
// Hide barIcon and show banIcon, textArea and confirmBox
confirmLink.bind('click', function() {
barIcon.hide();
banIcon.show();
textArea.show();
confirmBox.show();
});
// Hide banIcon, textArea, confirmBox and show barIcon
banIcon.bind('click', function() {
banIcon.hide();
textArea.hide();
confirmBox.hide();
barIcon.show();
confirmCheckbox.parent().removeClass('checked');
submitButton.addClass("disabled");
});
// Hide barIcon, textArea, confirmBox and show checkIcon after clicking the submitButton
submitButton.bind('click', function() {
banIcon.hide();
textArea.hide();
confirmBox.hide();
checkIcon.show();
confirmCheckbox.parent().removeClass('checked');
submitButton.addClass("disabled");
});
// checkbox functionality whithin the confirmBox
confirmCheckbox.on('ifChecked', function() {
submitButton.removeClass('disabled');
});
confirmCheckbox.on('ifUnchecked', function() {
submitButton.addClass('disabled');
});
});
}
}
});
HTML:
<table class="table table-hover">
<thead>
<tr>
<th>Ausbildung</th>
<th>Termine</th>
<th>Ausbildungsstätte</th>
</tr>
</thead>
<tbody>
<tr confirm>
<td>
<ul class="nav navbar-nav">
<li class="dropdown">
<a aria-expanded="false" role="button" data-target="#" class="dropdown-toggle config-menu config-menu-bars" data-toggle="dropdown">
<i class="fa fa-bars"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-ban" style="display: none;">
<i class="fa fa-ban"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-checked" style="display: none;">
<i class="fa fa-check-square-o"></i>
</a>
<ul role="menu" class="dropdown-menu">
<li><a class="confirm" data-target="">Bestätigen</a></li>
<li><a class="move" data-target="">Verschieben</a></li>
</ul>
</li>
</ul>
</td>
<td>
<p><strong>Ausbildungsname</strong></p>
<p>Kürzel</p>
</td>
<td>
<p><strong class="text-navy">28.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
<p><strong class="text-navy">29.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
<p><strong class="text-navy">30.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
</td>
<td>
<p><strong>Ausbildungsstätte Wunderfull ABC</strong></p>
<p>Musterstraße 1, 1234 Musterstadt</p>
<p><i class="fa fa-th-large"></i></span> Seminarraum, Kursraum, Fitnessfläche</p>
</td>
</tr>
<tr confirm>
<td>
<ul class="nav navbar-nav">
<li class="dropdown">
<a aria-expanded="false" role="button" data-target="#" class="dropdown-toggle config-menu config-menu-bars" data-toggle="dropdown">
<i class="fa fa-bars"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-ban" style="display: none;">
<i class="fa fa-ban"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-checked" style="display: none;">
<i class="fa fa-check-square-o"></i>
</a>
<ul role="menu" class="dropdown-menu">
<li><a class="confirm" data-target="">Bestätigen</a></li>
<li><a class="move" data-target="">Verschieben</a></li>
</ul>
</li>
</ul>
</td>
<td>
<p><strong>Ausbildungsname</strong></p>
<p>Kürzel</p>
</td>
<td>
<p><strong class="text-navy">28.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
<p><strong class="text-navy">29.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
</td>
<td>
<p><strong>Ausbildungsstätte Wunderfull ABC</strong></p>
<p>Musterstraße 1, 1234 Musterstadt</p>
<p><i class="fa fa-th-large"></i></span> Seminarraum, Kursraum, Fitnessfläche</p>
</td>
</tr>
<tr confirm>
<td>
<ul class="nav navbar-nav">
<li class="dropdown">
<a aria-expanded="false" role="button" data-target="#" class="dropdown-toggle config-menu config-menu-bars" data-toggle="dropdown">
<i class="fa fa-bars"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-ban" style="display: none;">
<i class="fa fa-ban"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-checked" style="display: none;">
<i class="fa fa-check-square-o"></i>
</a>
<ul role="menu" class="dropdown-menu">
<li><a class="confirm" data-target="">Bestätigen</a></li>
<li><a class="move" data-target="">Verschieben</a></li>
</ul>
</li>
</ul>
</td>
<td>
<p><strong>Ausbildungsname</strong></p>
<p>Kürzel</p>
</td>
<td>
<p><strong class="text-navy">28.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
</td>
<td>
<p><strong>Ausbildungsstätte Wunderfull ABC</strong></p>
<p>Musterstraße 1, 1234 Musterstadt</p>
<p><i class="fa fa-th-large"></i></span> Seminarraum, Kursraum, Fitnessfläche</p>
</td>
</tr>
</tbody>
</table>
</div>
<div class="panel panel-default confirm-panel accept-terminplanung" confirm>
<div class="panel-body text-muted ibox-heading">
<form action="#" method="post" role="form">
<div class="i-checks" ichecks>
<label class="">
<div class="icheckbox_square-green">
<input type="checkbox" class="i-checks appointment">
</div>
<p class="no-margins">Hiermit akzeptiere ich die Bedingungen des geschlossenen Dozentenvertrages und nehme den Bildungsauftrag für die ausgewählten Ausbildungen verbindlich an.</p>
</label>
</div>
<button type="button" name="termin-bestaetigen" class="btn btn-sm btn-w-m btn-warning submit-appointment disabled">Terminplanung übernehmen</button>
</form>
</div>
</div>
图片:
答案 0 :(得分:1)
您在指令中使用scope: true
。这样做是创建一个从父范围继承的新子范围,这与隔离范围不同。如果您在同一父级别上有多个指令(在您的情况下为confirm
),则它们将使用相同的子范围。
要说清楚:使用scope: true
将创建一个新的子范围,除非已经存在(例如由另一个指令创建)。所以在你的情况下,所有的确认指令都使用相同的范围。
您应该如何制作隔离范围?
scope: {...}
给它一个对象哈希。这将创建一个完全隔离的范围,这将允许指令在相同的范围级别上重用,而不会相互干扰。
您可以在此处找到有关此内容的更多信息:Angular JS Docs - Scope
scope属性可以是false,true或对象:
false(默认值):不会为该指令创建范围。该指令将使用其父级的范围。
true:将为指令的元素创建一个原型继承自其父级的新子范围。如果多个 对同一元素的指令请求一个新范围,只有一个新范围 已创建。
{...}(对象哈希):为指令的模板创建一个新的“隔离”范围。 “隔离”范围与正常范围不同 它没有原型继承其父范围。这是 在创建可重用组件时很有用,但不应该 意外地读取或修改父作用域中的数据。注意一个 隔离范围指令没有模板或templateUrl不会 将隔离范围应用于其子元素。
<强>更新强>
您使用confirm
四次,因此它会通过链接功能四次。每次通过链接功能时,您都会将某些功能绑定到页面上的按钮。名为termin-bestaetigen
的按钮有四个绑定到它的事件,confirm
上的tr
和div
上的confirm
三次。当您单击按钮时,所有这些事件都会触发,而在所有这些事件中,您不会检查任何内容,只是显示/隐藏所有内容。
在这种情况下,我建议您在更多一口大小的块中分解您的指令(至少将tr
和div
上的confirm
分开)并将某些功能指向一个控制器。您可以在true
指令中添加一个属性,您可以在指令中查看该属性,并且一旦该属性求值为id
,您就可以显示/隐藏任何内容。