简体   繁体   English

ng-show不适用于$ scope

[英]ng-show doesn't work with $scope

I'm new to angular and can't understand why the ng-show in the below code isn't working. 我是angular的新手,不明白为什么以下代码中的ng-show无法正常工作。 The isLoggedIn is a variable in $scope. isLoggedIn是$ scope中的变量。

<html ng-app"XYZ"
<body>
    <nav id="myNav" ng-show = "isLoggedIn" ng-controller="NavBarController as navCtrl">
        <div class="nav-wrapper">
            <a href="#!" class="brand-logo">Logo</a>
            <a href="#" data-activates="mobile-demo" class="button-collapse">
                <i class="material-icons">menu</i>
            </a>
            <ul class="side-nav" id="mobile-demo">
                <li>
                    <a href="sass.html">Sass</a>
                </li>
                <li>
                    <a href="badges.html">Components</a>
                </li>
                <li>
                    <a href="collapsible.html">Javascript</a>
                </li>
                <li>
                    <a href="mobile.html">Mobile</a>
                </li>
            </ul>
        </div>
    </nav>
    <div ng-view>

    </div>...</body></html>

Another template: 另一个模板:

 <button class = "btn" ng-click = "loginCtrl.doLogin()">LOGIN</button>

The loginCtrl: loginCtrl:

angular.module('XYZ')
.controller('LoginController', ['NetworkService',
    '$routeParams',
    '$location',
    '$scope',
    '$timeout',
    function(NetworkService, $routeParams, $location,$scope,$timeout) {
        var self = this;
        $scope.isLoggedIn = false;
        // $scope.$apply();
        self.doLogin = function(){
            $scope.isLoggedIn = true;
        }
    }
]);

I tried calling $scope.$apply() after I changed the isLoggedIn variable which results in an exception '$apply already in progress'. 我更改了isLoggedIn变量后尝试调用$ scope。$ apply(),这导致异常“ $ apply已经在进行中”。 I also tried encapsulating the doLogin's inner code in a $timeout() which also failed. 我还尝试将doLogin的内部代码封装在$ timeout()中,这也失败了。

EDIT: 编辑:

config: 配置:

angular.module('XYZ')
.config(function($routeProvider) {
    console.log("Configuring routes");
    $routeProvider.when('/login', {
            templateUrl: "./templates/login.html",
            controller: "LoginController",
            controllerAs: "loginCtrl"
        })
    });

The problem you are facing is that you are instantiating a new module, but it requires a second argument (the dependencies). 您面临的问题是您要实例化一个新模块,但是它需要第二个参数(依赖项)。

Since you aren't providing any dependencies, you actually do need to pass an empty array [] as a second parameter. 由于您没有提供任何依赖关系,因此实际上您确实需要传递一个空数组[]作为第二个参数。 And seeing you are using $routeProvider in your .config() you should have to include either the dependency provided by AngularJS or some other kind of "routing' dependency (such as ui-router ) 并看到您在.config()中使用$ routeProvider,您必须包含AngularJS提供的依赖项或其他“路由”依赖项(例如ui-router

So your code would have to look like this: 因此您的代码必须如下所示:

Config 设定档


angular.module('XYZ', ['ngRoute'])
.config(function($routeProvider) {
    console.log("Configuring routes");
    $routeProvider.when('/login', {
            templateUrl: "./templates/login.html",
            controller: "LoginController",
            controllerAs: "loginCtrl"
        })
    });

LoginController LoginController


angular.module('XYZ', ['ngRoute'])
.controller('LoginController', ['NetworkService',
    '$routeParams',
    '$location',
    '$scope',
    '$timeout',
    function(NetworkService, $routeParams, $location,$scope,$timeout) {
        var self = this;
        $scope.isLoggedIn = false;
        // $scope.$apply();
        self.doLogin = function(){
            $scope.isLoggedIn = true;
        }
    }
]);

it's also a bad practice to reinstantiate your module each time, so assign it to a variable ( var myApp = angular.module('XYZ', ['ngRoute']); ) and use that variable to instantiate controllers, services, factories, etc. 每次都重新实例化模块也是一种不好的做法,因此将其分配给变量( var myApp = angular.module('XYZ', ['ngRoute']); )并使用该变量实例化控制器,服务,工厂,等等

Here's a fiddle to show the functionality (incl. the URL to angular-route.js, which you will need if you're using routing). 这是用来显示功能的小提琴 (包括Angular-route.js的URL,如果您使用路由,则需要此URL)。 It's not an exact replica of your code because JSFiddle doesn't handle routing all too well. 它不是代码的精确副本,因为JSFiddle不能很好地处理路由。

your controller is called LoginController therefore ng-controller=LoginController, the controller also needs to be called in the parent tag to any other directives....see below fix. 您的控制器称为LoginController,因此ng-controller = LoginController,该控制器还需要在父标记中调用到其他任何指令。...请参见以下修复。

<body ng-controller="LoginController">
<nav id="myNav" ng-show = "isLoggedIn" >
    <div class="nav-wrapper">
        <a href="#!" class="brand-logo">Logo</a>
        <a href="#" data-activates="mobile-demo" class="button-collapse">
            <i class="material-icons">menu</i>
        </a>
        <ul class="side-nav" id="mobile-demo">
            <li>
                <a href="sass.html">Sass</a>
            </li>
            <li>
                <a href="badges.html">Components</a>
            </li>
            <li>
                <a href="collapsible.html">Javascript</a>
            </li>
            <li>
                <a href="mobile.html">Mobile</a>
            </li>
        </ul>
    </div>
</nav>
<div ng-view>

</div>...</body></html>
angular.module('XYZ')
.controller('LoginController', ['$routeParams',
    '$location',
    '$scope',
    '$timeout',
    function($scope) {

    $scope.isLoggedIn = false;

    $scope.doLogin = function(){
        $scope.isLoggedIn = true;
    };
}
]);

You need not a create a service for simply setting $scope of object to true or false, you can handle it using controller itself. 您无需创建用于简单地将$ scope对象设置为true或false的服务,就可以使用控制器本身来处理它。 And in HTML, do the following change for ng-click 在HTML中,对ng-click进行以下更改

 <button class = "btn" ng-click = "doLogin()">LOGIN</button>

This should work. 这应该工作。

I solved it. 我解决了 The problem was that the element I wanted to hide (or show) was out of LoginController's scope. 问题是我要隐藏(或显示)的元素不在LoginController的范围内。 Since $scope.isLoggedIn is being changed in the controller's scope, $scope is not aware of the HTML it needs to change which is not in the same scope. 由于$ scope.isLoggedIn在控制器的作用域中被更改,因此$ scope不知道需要更改的HTML不在同一作用域中。 Putting 'isLoggedIn' in $rootScope works. 将'isLoggedIn'放入$ rootScope即可。 Thanks to @Jorrex for helping and giving me the solution and everyone who tried to help me. 感谢@Jorrex的帮助并为我提供了解决方案,以及所有尝试帮助我的人。

//solution
app.controller('LoginController', ['NetworkService', '$routeParams',
'$location',
'$scope',
'$timeout',
'$rootScope',
function(NetworkService, $routeParams, $location,$scope,$timeout,$rootScope) {

        $scope.doLogin = function(){
            $rootScope.isLoggedIn = true;
        }
    }
]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM