【问题标题】:Strage behavior of ng-class when ng-if is used使用 ngif 时 ngclass 的奇怪行为
【发布时间】:2015-03-16 16:44:33
【问题描述】:

我有这段代码:

....
<article class="collapse navbar-collapse">
    <ul ng-if="isLogged()" class="nav navbar-nav">
        <li ng-class="{'active': activeUrl === 'projects'}">
            <a href="#/projects" ng-click="activeUrl='projects'">Projects</a>
        </li>
        <li ng-if="isAdmin()" ng-class="{'active': activeUrl === 'admin'}">
            <a href="#/admin" ng-click="activeUrl='admin'">Administration</a>
        </li>
    </ul>
</article>

点击链接时应该添加active类。在我添加模拟用户身份验证的 ng-if 表达式之前,它运行得非常好。现在,当它添加一次active 类时,单击另一个导航链接时它不会删除该类 - 看起来同时打开了 2 个页面。 applicationController 有模拟功能:

applicationController= function($scope, Restangular, userService){
    $scope.activeUrl = "admin";
    $scope.data = {
        user: {
        email: undefined,
        password: undefined
        }
    };

    $scope.login = function(user){
        //login mock
    };

    $scope.isLogged = function(){
        return userService.isLogged();
    };

     $scope.isAdmin = function(){
        return userService.isAdmin();
    };
};

并且userService 具有确定用户是否经过身份验证以及是否是管理员的逻辑。我不认为 ng-ifng-class 在一个 HTML 元素中是什么不寻常的东西,这就是为什么我认为我必须犯一些我看不到的简单错误。单击后是否重新创建范围?如果有人帮助我,我会很高兴 - 提前谢谢你! 更新:有@ptwo 帮助的解决方案,我需要$parent 和管理$parent.$parent

<article class="collapse navbar-collapse">
    <ul ng-if="isLogged()" class="nav navbar-nav">
        <li ng-class="{'active': $parent.activeUrl === 'projects'}">
           <a href="#/projects" ng-click="$parent.activeUrl='projects'">Projects</a>
        </li>
        <li ng-if="isAdmin()" ng-class="{'active': $parent.$parent.activeUrl === 'admin'}">
           <a href="#/admin" ng-click="$parent.$parent.activeUrl='admin'">Administration</a>
        </li>
      </ul>
</article>

更新 2 解决方案不直接访问 $parent,但在 applicationController 中使用 data 对象,这允许我访问 activeUrl

<article class="collapse navbar-collapse">
    <ul ng-if="isLogged()" class="nav navbar-nav">
        <li ng-class="{'active': data.activeUrl === 'projects'}">
            <a href="#/projects" ng-click="data.activeUrl='projects'">Projects</a>
        </li>
        <li ng-if="isAdmin()" ng-class="{'active': data.activeUrl === 'admin'}">
            <a href="#/admin" ng-click="data.activeUrl='admin'">Administration</a>
        </li>
    </ul>
</article>

applicationController= function($scope, Restangular, userService){
    $scope.data = {
        activeUrl: "admin",
        user: {
            email: undefined,
            password: undefined
        }
};
....

【问题讨论】:

  • 请参阅here,但请注意第二个答案(不是接受的答案)。通过使用$parent 访问外部变量,您现在可以解决问题,但如果您出于任何其他原因添加新范围,则可能会在未来看到它再次出现。
  • @Nobita 你说得对,我放置了另一个没有$parent但使用data.activeUrl的工作解决方案

标签: javascript angularjs twitter-bootstrap twitter-bootstrap-3 angularjs-scope


【解决方案1】:

使用函数来更改 activeUrl。在视图中包含表达式从来都不是一个好习惯。

<article class="collapse navbar-collapse">
<ul ng-if="isLogged()" class="nav navbar-nav">
    <li ng-class="{'active': isActiveUrl('projects')}">
        <a href="#/projects" ng-click="updateActiveUrl('projects')">Projects</a>
    </li>
    <li ng-if="isAdmin()" ng-class="{'active': isActiveUrl('admin')}">
        <a href="#/admin" ng-click="updateActiveUrl('admin')">Administration</a>
    </li>
</ul>
</article>

applicationController= function($scope, Restangular, userService){
    $scope.data = {
        activeUrl: "admin",
        user: {
            email: undefined,
            password: undefined
        } };
    $scope.isActiveUrl = isActiveUrl;
    $scope.updateActiveUrl = updateActiveUrl;

    function isActiveUrl(param){
      return $scope.data.activeUrl == param;
    }

    function updateActiveUrl(param){
      $scope.data.activeUrl = param;
    }
}

想法是从自己的作用域改变父作用域的成员变量,而不是ng-if的子作用域。

【讨论】:

【解决方案2】:

当您使用 ng-if 时,它会添加自己的范围,因此在单击时,activeUrl 会设置在控制器的子范围内。尝试使用$parent.activeUrl='admin' 它应该可以工作

【讨论】:

  • 只需稍加改动,您的解决方案就可以很好地工作 - 谢谢 :)
猜你喜欢
  • 2018-02-18
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-17
  • 2011-07-14
相关资源
最近更新 更多