ng-class绑定到子范围中的不同变量,而不是分配给变量

时间:2015-11-08 19:11:03

标签: javascript html css angularjs

我有一个父范围和一个子范围,每个范围都有ng-class =“some-class:boolean”的标签。子范围变量在单击函数中设置为“true”。父函数在。$ on函数中设置为'true'。触发。$ on时,变量按预期设置为“true”,但不会将类名应用于标记。

真正奇怪的是,当子范围的变量设置为true时,它将正确的类应用于BOTH元素。变量是完全不同的名称,类也是如此。

我做错了什么?

控制器

var app = angular.module('profileApp', []);

    app.controller('ProfileController', ['$scope', function($scope){
    $scope.contentVisible = false;
    $scope.$on('animationEnd', function(){
        $scope.contentVisible = true;
    });
}]);

//DIRECTIVES
app.directive('introSection', function(){
return {
    restrict: 'E',
    templateUrl: 'templates/intro-section.html',
    controller: function($scope){
        $('#cityOutline svg').one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function(e) {
            $scope.$emit('animationEnd');
        });
     }
  }
});
app.directive('experienceSection', function(){
    return {
        restrict: 'E',
        templateUrl: 'templates/experience-section.html',
        controller: function($scope){
            $scope.toggleDetails = false;

            $scope.showDetails = function(){
                $scope.toggleDetails = true;
            };
            $scope.hideDetails = function(){
                $scope.toggleDetails = false;
            };
        }
    }
});

HTML

<html lang="en" ng-app="profileApp">
<head>
  <script src="js/lib/angular.js" type="text/javascript"></script>
  <script src="js/controllers/profileController.js" type="text/javascript"></script>
</head>
<body ng-controller="ProfileController">
  <header id="nav" ng-class="{'visible': contentVisible}">
  </header>
<experience-section>
  <div id="project-details" ng-class="{'open': toggleDetails}">
    <button type="button" class="close" ng-click="hideDetails()">X</button>
  </div>
  <button type="button" class="flat-button" ng-click="showDetails()">View Details</button>
</experience-section>

2 个答案:

答案 0 :(得分:2)

好这是一个常见的错误。为了知道作用域内的内容何时发生了变化,需要运行一个摘要周期来对作用域的所有内容进行脏检查,然后通知视图他们需要更新。 (如果您想了解更多信息,请参阅官方文档:https://docs.angularjs.org/guide/scope

通常情况下,你几乎不必担心这个消化周期,角度是自动为你做的...只要你留在有角度的世界中。当我说出角度的世界时,我的意思是角度的DOM事件绑定之一(如ng-clickng-changeng-touch ......)和{{1服务。

在您的情况下,当您这样做时:

$timeout
不幸的是,你不再处于棱角分明的世界。这意味着当你发出&#34; animationEnd&#34;事件(即使你用角度&#39;助手$ on和$ emit发射它)角度摘要周期也不会被触发,而角度也不知道值已经改变,所以它无法更新视图。

因此,在您的情况下,解决方案只是在$('#cityOutline svg').one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function(e) { $scope.$emit('animationEnd'); }); 之后调用$scope.$apply();。这样,您可以强制角度检查是否有任何更改。 所以你的代码看起来像那样:

$scope.$emit()

所以,当您点击“关闭”时,您会遇到奇怪的行为。按钮:

  • 动画动画事件被触发(显然是由jQuery);
  • 您的代码更新了范围的值;
  • angular现在没有检测到这种变化,因为没有调用摘要周期;
  • 您点击关闭按钮;
  • 您的代码更新了其他范围的值;
  • 现在,angular正在运行它的摘要周期;
  • 它检测到(刚才)这两个值已经改变;
  • 然后它告诉视图事情已经改变,他们需要更新。

因此视图仅在ng-click发生后更新,这就是单击时应用这两个类的原因。

希望它会对你有所帮助:)。

答案 1 :(得分:1)

动画结束时,您的更改不适用。基本上,当您单击切换按钮时,它的工作原理是手表正在更新并将更改应用于contentVisibility范围变量。在$ on中,在最后添加$ scope。$ apply(),这将在动画结束时正确添加类。

$scope.$on('animationEnd', function(){
    $scope.contentVisible = true;
    $scope.$apply();
});

这是一个插件。 http://plnkr.co/edit/KRbxJiZOJRSvZhaNKTB1?p=preview