【问题标题】:ngHide directive only works with ngRoute module after page refreshngHide 指令仅在页面刷新后与 ngRoute 模块一起使用
【发布时间】:2016-01-28 14:41:43
【问题描述】:

当我登录我的应用程序时,我希望登录和注册按钮从导航中消失,因此如果登录成功并且从服务器接收到令牌,我将使用 ng-hide 指令,并将其存储在 cookie 中.

Nav 是 index.html 文件的一部分。

因为我使用的是角度路由,所以当登录成功时,index.html 不会再次加载,而是通过 ng-view 指令渲染主页。

问题是我必须刷新页面才能使 ng-hide 工作。我假设这是因为 ng-hide 是 index.html 页面的一部分,不会重新加载。

希望有比每次有人登录时都刷新页面更好的解决方案。

这是我的一些相关代码。

HTML

<!-- Navigation -->
<nav class="navbar navbar-custom navbar-fixed-top" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
                <i class="fa fa-bars"></i>
            </button>
            <a class="navbar-brand page-scroll" href="#/">
                <i class="fa fa-play-circle"></i>  <span class="light">Webnar</span>
            </a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse navbar-right navbar-main-collapse">
            <ul class="nav navbar-nav">
                <!-- Hidden li included to remove active class from about link when scrolled up past about section -->
                <li class="hidden">
                    <a href="#page-top"></a>
                </li>
                <li>
                    <a class="page-scroll" href="#about">Webinars</a>
                </li>
                <li ng-hide="token">
                    <a class="page-scroll" href="#/login">Login</a>
                </li>
                <li ng-show="token">
                    <a class="page-scroll " href="#/create">Add a webinar</a>
                </li>
                <li ng-hide="token">
                    <a class="page-scroll btn btn-default " href="#/signup">Sign Up</a>
                </li>
                <li ng-show="token" >
                  <a class="page-scroll btn btn-default" ng-click="logOut()">Logout</a>
                </li>

            </ul>
        </div>
        <!-- /.navbar-collapse -->
    </div>
    <!-- /.container -->
</nav>

App.js

var webinarApp = angular.module('webinarApp', ['ngCookies', 'ngRoute']);

webinarApp.config(function($routeProvider){

    $routeProvider

    .when('/', {
      templateUrl: './home.html',
      controller: 'mainController'
    })
    .when('/signup', {
      templateUrl: './signup.html',
      controller: 'mainController'
    })
    .when('/login', {
      templateUrl: './login.html',
      controller: 'mainController'
    })
    .when('/create', {
      templateUrl: './create.html',
      controller: 'mainController'
    })
});

webinarApp.controller('mainController', ['$scope', '$http', '$cookies', '$location', function($scope, $http, $cookies, $location){

  $scope.welcomeMessage = '';
  $scope.users = [];
  $scope.searchQuery = "";
  $scope.orderByField = 'name';
  $scope.newUser = {};
  $scope.logInUser = {};
  $scope.webinars = [];
  $scope.newWebinar = {};
  $scope.isDisabled = false;


  // ============== Users ================

  $scope.getUsers = function(){
    $http.get('/api/users').then(function(response){
      $scope.users = response.data;
    });
  };
  $scope.getUsers();

  $scope.createUser = function(){
    $http.post('/api/users', $scope.newUser).then(function(response){
      console.log(response.data)
      $scope.users.push(response.data);
      $scope.newUser = {};
      $location.path('/login');
    });
  };

  $scope.obtainToken = function(){
    $http.post("/api/users/authentication_token", $scope.logInUser).then(function(reponse){
      $scope.token = reponse.data.token;
      console.log($scope.token);
      $cookies.put('token', $scope.token);
      $location.path('/')
    });
  };

【问题讨论】:

  • 使用 ng-if 怎么样?而不是 ng-hide 和 ng-show.On 成功登录时提供 $scope.variable 并将其提供给 ui 中的 ng-if。
  • ng-if 也不起作用。
  • @ViditSaxena : 请创建一个 plunkr 并提供给我们

标签: javascript html angularjs ngroute ng-hide


【解决方案1】:

这是因为您将导航栏放在了索引页上。它不是由路由模块加载的模板。所以它与任何与之绑定的路由和控制器无关。在路由中声明的控制器只适用于路由模块加载的模板。

要绑定控制器,无论路由是使用 ng-controller 指令。把它放在你的 &lt;nav&gt; 元素上

请注意,如果您使用“作为控制器”语法,则必须在控制器中执行: this.isDisabled 代替 $scope.isDisabled

文档:https://docs.angularjs.org/#!/api/ng/directive/ngController

如果您需要使用应用程序的其余部分将数据更新到该控制器。使用 $rootScope。如果你使用 'ctrl as' 语法,更容易做到: this.$rootScope=$rootScope;

如果您不喜欢这样,请使用 $watch 来监视更改并将 currentValue 重新绑定到控制器:

$rootScope.watch('myParameter', function(new){
     this.myParameter = new;
});

并且不要忘记初始化 $ROOTSCOPE 中的变量。否则该变量将最终出现在导航栏控制器不可见的子范围内。

【讨论】:

  • 如何将 index.html 的 设为 ???
  • 坏主意,你有一个 ng-route 正在用一个身体的孩子做他的事情。最好将导航栏控制器与路由使用的控制器分开。如果你只有一个控制器,就像这里显示的演示代码一样,你可以,但我绝对不推荐它用于真正的应用程序,我什至不知道这是否可行。
  • 谢谢!!即使我不确定它是否会起作用..但这只是一个想法。
  • 我已经将 body 元素绑定到 ng-controller="mainController" 并且不起作用。所以我将通过@walfrat 尝试这个解决方案
  • 所以上面的工作。我在包含导航栏的 body 元素标签上使用了 mainController。我没有将令牌存储在 $scope 中,而是将其存储在 $rootscope 中。 @walrat - 我的问题是刷新页面时它是如何工作的?
【解决方案2】:

您应该使用其他变量声明来声明 $scope.token。当您最初设置 ng-hide 时,它​​不存在于范围内。

$scope.isDisabled = false; 
$scope.token;

【讨论】:

  • 没用。不过谢谢,我应该首先这样做。
【解决方案3】:

您是否尝试过使用 $scope.$apply() ???

  $scope.$apply(function() {
    $scope.token = <whatever value>;
  })

【讨论】:

  • 我做了,但它说摘要循环已经在进行中。这是正确的,因为我从未脱离 Angular 上下文。不过谢谢
【解决方案4】:

好的,我认为一种方法是为导航添加一个控制器,比如 navbarController。

    <nav ng-controller="navbarController">...</nav>

Inject $rootScope into both maincontroller and navbarController.

然后在 mainController 中,每当您需要更改令牌的值时,请执行此操作

$rootScope.$emit('tokenValueChange', <value>);

then in navbarController add,

$rootScope.$on('tokenValueChange', function(newValue) {
    $scope.token = newValue;
})

I am not sure if this is a perfect method but this should work.

【讨论】:

  • 那么mainController中的就是token值?
【解决方案5】:

我遇到了与 OP (viditsaxena) 类似的问题,并以与他相同的方式解决了它。和他一样,我的导航中有ng-hide,它位于 index.html 中。我的ng-hides 在初始页面加载时工作正常,但是当我尝试导航到不同的视图时,我的ng-hides 在我刷新页面之前无法工作。

我的解决方案:与@viditsaxena 在接受的答案下的 cmets 中描述的方式相同(使用 $rootScope 而不是 $scope),但我想我会把我的实际代码放在这里,向您展示我是如何让它在我的app.js 文件:

我从此离开(导航离开原始视图后,ng-hide 需要刷新才能加载):

app.controller('routeController', ['$scope', '$location', function($scope, $location) {
    $scope.showPortfolioHeader = $location.path() === '/jcRealty';
}]);

对此(现在我的 ng-hides 在我离开第一个视图后不需要刷新):

app.controller('routeController', ['$rootScope', '$location', function($rootScope, $location) {
    $rootScope.showPortfolioHeader = $location.path() === '/jcRealty';
}]);

接受的答案让我成功了,但我很难破译他回复中的一些语法。我自己的测试证实了他所说的一些内容。我上面的控制器 (routeController) 与位于 /jcRealty 路径的视图相关。如果我将ng-hides 放在我的 jcRealty 视图中,它们使用$scope 可以正常工作(无需刷新)。但由于我的 ng-hide 位于 index.html 上,在该控制器的路径之外,因此需要 $rootScope 而不需要重新加载页面。

【讨论】:

    猜你喜欢
    • 2018-09-16
    • 2015-02-16
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    相关资源
    最近更新 更多