我有一个自定义指令,它根据主控制器上的变量打开该部分。如果您单击某个部分的标题(标题),它将打开它并关闭其余部分。但是当我在一个部分中有一个更新变量的按钮时,它将恢复为旧值。
app.directive('sliders', function () {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: function ($scope) {
$scope.sliders = [];
this.addSlider = function (section, element) {
$scope.sliders.push(section);
};
this.select = function (section) {
console.log(' select ' + $scope.$parent.stepToShow);
$scope.$parent.stepToShow = section.step;
};
},
template: '<div class="sliders" ng-transclude></div>'
};
})
.directive('sliderSection', function () {
return {
restrict: 'E',
require: '^sliders',
transclude: true,
scope: {
title: '@',
step: '@'
},
link: function (scope, element, attrs, slidersCtrl) {
scope.selected = function () {
return scope.step == scope.$parent.$parent.stepToShow;
};
scope.select = function () {
console.log('select() ' + scope.step);
slidersCtrl.select(scope);
};
slidersCtrl.addSlider(scope);
scope.$watch(function () { return scope.$parent.$parent.stepToShow; }, function (newVal, oldVal) {
console.log(' watch ' + scope.$parent.$parent.stepToShow);
if (newVal == scope.step) {
element.find('.slider-body').slideDown();
}
else {
element.find('.slider-body').slideUp();
}
});
},
template: '<div id="" class="slider-section" step="{{step}}" ng-click="select()">' +
'<div class="slider-header" >{{title}}</div>' +
'<div class="slider-body" ng-transclude></div>' +
'<div>'
};
});
如果我通过plunkr向你展示它会更好
答案 0 :(得分:1)
按钮上有一个点击处理程序,但你的父母也有一个点击处理程序。当您单击按钮以使它们相互抵消时,两个事件都将触发
您需要阻止按钮单击传播,或者您需要在父点击上检查事件目标。
阻止传播在$event
传递给ng-click
处理程序。
<button ng-click="setStepToShow('1', $event)">Next Step</button>
然后在处理程序代码中:
$scope.setStepToShow = function (step, $event) {
$event.stopPropagation()
/* other code as original */
}
不使用if...$$phase
,而是$apply()
,而只使用$timeout()
的 DEMO 强>