angularjs:被监视的变量不断恢复旧值

时间:2014-11-04 02:26:36

标签: javascript angularjs angularjs-directive angularjs-scope

我有一个自定义指令,它根据主控制器上的变量打开该部分。如果您单击某个部分的标题(标题),它将打开它并关闭其余部分。但是当我在一个部分中有一个更新变量的按钮时,它将恢复为旧值。

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向你展示它会更好

http://plnkr.co/edit/aFMkWYmINb26M8cJFzgl?p=preview

1 个答案:

答案 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