gpt4 book ai didi

javascript - Angular 未在 ng-view 上更新 ng-class

转载 作者:行者123 更新时间:2023-12-04 15:40:04 24 4
gpt4 key购买 nike

我在我的 Angular 应用程序中使用 angular 1.6.5 并遇到了一个非常奇怪的行为。

我想要实现的是:当 ngroute 被更改时,我必须从当前 View 中删除事件类,等待离开动画完成,然后将事件类添加到新 View 。

我已经在配置中设置了应用程序和路由。

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

app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl:"home.html",
reloadOnSearch:false
})
.when('/about-us', {
templateUrl:"about.html",
reloadOnSearch:false
})
.when('/contact', {
templateUrl:"contact.html",
reloadOnSearch:false
})
.otherwise({
template : "<h1>None</h1><p>Nothing has been selected</p>"
});
});

我有一项服务,我存储动画时间和 bool 值,指示 View 的可见性:
app.service('animationProperties', function () {
this.animationTimings = {
views: 1000
};
this.visibility = {
view : false
};
});

我有一个具有简单调试功能的主 Controller 和一个 onRouteChangeStart 函数,它应该从当前 View 中删除事件类(通过使 View 可见性 bool 值为 false):
app.controller('MainCtrl', function ($scope, $window, $location, 
animationProperties) {

$scope.animationProperties = animationProperties;

$scope.$on('$routeChangeStart',function () {
animationProperties.visibility.view = false;
});

$scope.toggleActive = function(){
$scope.animationProperties.visibility.view = !$scope.animationProperties.visibility.view;
}
});

最后一件事,等待离开动画完成的 ngAnimate,然后删除当前 View (使用 done() 方法)并通过将可见性 bool 值设为 true 再次进入新 View :
app.animation('.view', function($timeout, animationProperties) {
return {
enter: function(element, done) {
$timeout(function () {
animationProperties.visibility.view = true;
$timeout(function () {
done();
}, animationProperties.animationTimings.views);//Wait to enter
},animationProperties.animationTimings.views); //Wait for leave function
},
leave: function(element, done) {
$timeout(function () {
done();
}, animationProperties.animationTimings.views);
}
}
});

这里是 plunker

第一次(从导航)切换页面时,您会看到一切正常,但是当第二次转到页面时, View 类没有更新,因此没有播放动画。在调试时,您可以清楚地看到可见性 bool 值已正确更新,但离开 View 时的 ng-class 未得到更新。

您的帮助将不胜感激!!!

最佳答案

引用我自己来自 here :

这是正在发生的事情:

  • $routeChangeStart ,您更改(一旦评估)将告诉 ngClass 的值删除 active从离开的 Angular 上课。
  • 同时,$route开始准备进入 View ,包括获取它的模板。
  • 一旦一切准备就绪,它就会触发 $routeChangeSuccess事件,它发出信号 ngView开始交换两个 View 。
  • 在交换过程中,ngView破坏离开 View 的作用域,从那时起作用域的观察者不再被……观察。

  • 因此,如果步骤 1-4 发生得足够快,则在为 ngClass 评估必要的表达式之前,将破坏离开 View 的范围。删除 active类(class)。第一次访问路线时,动画有效,因为 $route必须对进入 View 的模板发出服务器请求(这给了 ngClass 时间来完成它的工作)。但是,当您访问之前访问过的路线时,模板已经被缓存并且过渡很快。

    您可以通过故意减慢模板检索速度来解决此问题(即使是虚拟机轮次也足够了)。例如:
    app.decorator('$templateRequest', ($delegate, $timeout) => {
    const $templateRequest = (...args) => $delegate(...args).
    then(tmpl => $timeout().then(() => tmpl));
    Object.defineProperty($templateRequest, 'totalPendingRequests', {
    get: () => $delegate.totalPendingRequests,
    set: nv => $delegate.totalPendingRequests = nv,
    });
    return $templateRequest;
    });

    ( Updated plnkr 1)

    另一种解决方法是实现您自己的、简单的、同步版本的 ngClass。 ,以便在离开 View 的范围被销毁之前立即应用类。此类指令的粗略、未优化、非生产就绪版本可能如下所示:
    app.directive('myClass', () => (scope, elem, attrs) => {
    scope.$watchCollection(attrs.myClass, newValue => {
    Object.keys(newValue).forEach(c => {
    if (newValue[c]) {
    elem.addClass(c);
    } else {
    elem.removeClass(c);
    }
    });
    });
    });

    ( Updated plnkr 2)

    话虽如此,您的设置似乎很奇怪:
  • 监听事件 ($routeChangeStart)。
  • 设置触发 animationProperties.visibility.views 的标志 ( ngClass )删除一个类。
  • 删除类,触发 CSS 动画。
  • 同时,让自定义 JavaScript 动画 (animation('.view')) 与 CSS 动画同步,然后设置标志。
  • 通过重新设置标志,为进入 View 触发相反的 CSS 动画。

  • 😕

    对于初学者,为什么同时使用 CSS 和 JS 动画?例如,您可以处理 JS 动画的不透明度变化(假设您的实际设置更复杂,并且需要 JS 动画来获得其他效果)。

    或者,您可以使用基于自动添加/删除的纯 CSS 动画更轻松地处理淡入/淡出 ng-enter/ ng-leave类(它只是 4 个微小的 CSS 规则 :smiley :):
    [ng-view].ng-enter {
    /* Wait for the leaving view to...leave, then start transitioning in. */
    transition: opacity 1s ease 1s;
    }

    [ng-view].ng-leave {
    /* Start transitioning out. */
    transition: opacity 1s ease;
    }

    [ng-view].ng-enter,
    [ng-view].ng-leave.ng-leave-active {
    /*
    * At the beginning of the entering animation and
    * at the end of the leaving animation,
    * the view must be fully invisible.
    */
    opacity: 0;
    }

    [ng-view].ng-enter.ng-enter-active,
    [ng-view].ng-leave {
    /*
    * At the end of the entering animation and
    * at the beginning of the leaving animation,
    * the view must be fully visible.
    */
    opacity: 1;
    }

    ( Updated plnkr 3)

    关于javascript - Angular 未在 ng-view 上更新 ng-class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46365402/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com