javascript - ng-class 绑定(bind)到子作用域中的不同变量而不是分配的变量

标签 javascript html css angularjs

我有一个父作用域和一个子作用域,每个作用域都有带有 ng-class="some-class: boolean"的标签。子作用域变量在点击函数中设置为“true”。父项在 .$on 函数中设置为“真”。当 .$on 被触发时,变量会按预期设置为“true”,但它不会将类名应用于标签。

真正奇怪的是,当子作用域的变量设置为 true 时,它​​会将正确的类应用于两个元素。变量是完全不同的名称,类也是如此。

我做错了什么?

Controller

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>

最佳答案

好的,这是一个常见的错误。为了知道范围内的事物何时发生变化,angular 需要运行一个摘要循环来对范围内的所有内容进行脏检查,然后可以通知 View 它们需要更新。 (如果您想了解更多信息,请参阅官方文档:https://docs.angularjs.org/guide/scope)

通常,您几乎不必担心摘要周期,angular 会自动为您完成……只要您留在 angular 的“世界”中。当我说 Angular 的世界时,我指的是 Angular 的 DOM 事件绑定(bind)之一(如 ng-clickng-changeng-touch .. .) 和 $timeout 服务。

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

$('#cityOutline svg').one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function(e) { 
         $scope.$emit('animationEnd');
});

不幸的是,你已经不在 Angular 的世界里了。这意味着当您发出“animationEnd”事件时(即使您使用 Angular 的助手 $on 和 $emit 发出它) Angular 摘要循环也不会被触发并且 Angular 不知道该值已更改,因此它无法更新 View 。

因此在您的情况下,解决方案只是在 $scope.$emit() 之后调用 $scope.$apply();。这样你就可以强制 Angular 检查是否有任何变化。 所以你的代码看起来像这样:

$('#cityOutline svg').one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function(e) { 
         $scope.$emit('animationEnd');
         $scope.$apply();
});

下面是当您单击“关闭”按钮时出现的奇怪行为:

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

因此 View 仅在 ng-click 发生后更新,这就是为什么在您单击时应用这两个类的原因。

希望对你有帮助:)

关于javascript - ng-class 绑定(bind)到子作用域中的不同变量而不是分配的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33597876/

相关文章:

html - 缩放 SVG 形状以适应内容,其中内容包括 foreignObject

html - 尝试访问 ibm 云对象存储桶内的文件并收到 CORS 错误

javascript - 无需滚动即可将单词换行到下一行

html - 如何使用 lang 指定输入按钮的语言?

javascript - SoundCloud SDK 在生产环境中不接收 token 回调,仅在 Safari 中

javascript - 为什么支持非js

javascript - 如何在 GNOME 中获取事件窗口的监视器?

javascript - 当我到达某个点时使 div 滚动

html - 如何在 CSS 中制作没有图像的自定义选择选项菜单样式?

javascript - 在单击时隐藏的视频上创建 div 和图像覆盖