ui router ng click事件未被触发

时间:2015-09-08 02:45:58

标签: javascript angularjs angular-ui-router

我在一个没有被解雇的状态下有一个ng-click方法。我尝试将事件附加到$rootScope对象,但结果仍然没有被触发。

HTML:

<div id="wrapper" class="toggled">
    <div id="sidebar-wrapper" ng-show="showMenu">
        <ul class="sidebar-nav">
            <li class="sidebar-brand">
                <a href="#">Test 1</a>
            </li>
        </ul>
    </div><!-- #sidebar-wrapper -->

    <div id="page-content-wrapper">
        <div class="container">
            <div ui-view></div>
        </div>
    </div>

    <button type="button" id="menu-toggle" class="btn btn-primary" ng-click="toggleMenu()" ng-show="showMenuBtn">Menu</button>
</div><!-- wrapper -->

JS -

var app = angular.module('app', ['ui.router']);

app.config(function ($stateProvider, $urlRouterProvider){

$urlRouterProvider.otherwise('/login');

$stateProvider
.state('login', {
    url : '/login',
    templateUrl : 'login.html',
    controller : function ($scope, $http, $state, $rootScope){

        //menu visbility toggle
        $rootScope.showMenu = false

        //show menu button
        $rootScope.showMenuBtn = false

        //login functionality.
        $scope.login = function(){
            if ($scope.formdata.username != "" && $scope.formdata.password != "")
            {
                $http.post('/login', $scope.formdata)
                .success(function (data){
                    console.log(data)
                    if (data.loginFlag){
                        $state.go('main')
                    }
                })
                .error(function (data){
                    console.log("Error", data)
                });
            } else {

            }
        }

        //changing state to signup
        $scope.goToSignUp = function(){
            $state.go('signup')
        }
    }
})

.state('signup',{
    url: '/signup',
    templateUrl: 'signup.html',
    controller: function ($scope, $http, $state){

        //changing state to login
        $scope.goBackToSign = function(){
            $state.go('login')
        }
    }
})

.state('main',{
    url: '/main',
    templateUrl: 'main.html',
    controller: function ($scope, $http, $state, $rootScope){

        //menu visibility toggle
        $rootScope.showMenu = true

        //show menu button
        $rootScope.showMenuBtn = true

        //toggle class for menu display/no display
        $scope.toggleMenu = function()
        {
            angular.element(document.getElementById(wrapper)).toggleClass('toggled');
        }

    }
})

});

5 个答案:

答案 0 :(得分:1)

在angularjs中,您应该使用ng-class来切换类。

所以你可以做这样的事情

HTML:

"click mniOpenExisting": function (event) {
    return 'openExistingTemplate';
    // In actuality, I will use:
    //Session.set('curTemplate', 'openExistingTemplate');
}

JS(在您的控制器内):

//ng-class="{'<class name>': <statement>}" 
//class is applied if the statement occurs (or is true)
<div id="wrapper" ng-class="{'toggled': toggle}">
    ...
</div><!-- wrapper -->

我建议您在上面针对ng-class发布的链接中阅读AngularJS文档中的更多内容,您可以在那里学到很多东西。 还有约翰帕帕的style guide,非常酷的东西!

答案 1 :(得分:1)

你应该在角度上使用ng-class。第二个问题是你正在使用

$scope.toggle = true;

您无法访问该范围,因为当您调用main.html时,该范围来自控制器,因此您无法像在尝试时那样在控制器外访问它(在ui-view之外)。

这就是为什么使用$ rootScope的解决方案有效的原因,如果您使用我的上述解决方案但是可以正常工作

...
$rootScope.toggle = true;
//toggle class for menu display/no display
$rootScope.toggleMenu = function()
{
    $rootScope.toggle = !$rootScope.toggle;
}
...

但这只是不好的做法。 就像我上面说过的那样,你真的应该阅读John Papa的角度风格指南,你应该在你的代码中做那些东西,使其更具可读性和可理解性,比如命名控制器等等。

因此,当您想要访问控制器外部的变量时,您应该为此创建服务或工厂。 因此,我只会向您展示我对您的代码所做的工作,如果您有疑问,请发表评论:D

的index.html:

<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <title>Login App</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">   </script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
    <script src="/js/app.js"></script>
    <script src="/js/bootstrap.js"></script>
    <link rel="stylesheet" href="/stylesheets/bootstrap.css"/>
    <link rel="stylesheet" href="/stylesheets/style.css"/>

</head>
<body ng-controller="AppController as appCtrl">

    <div id="wrapper" ng-class="{'toggled': menuUtil.toggle}">
         <div id="sidebar-wrapper" ng-show="menuUtil.showMenu">
            <ul class="sidebar-nav">
                <li class="sidebar-brand">
                    <a href="#">Test 1</a>
                </li>
            </ul>
         </div><!-- #sidebar-wrapper -->

         <div id="page-content-wrapper">
             <div class="container">
                 <div ui-view></div>
             </div>
         </div>
    </div><!-- wrapper -->

    <script src="/js/app.controller.js"></script>
    <script src="/js/menuUtil.js"></script>

</body>
</html>

main.html中:

<button type="button" id="menu-toggle" class="btn btn-primary" ng-click="toggleMenu()" ng-show="menuUtil.showMenuBtn">Menu</button> 

app.js:

 (function () {
    'use strict';

    angular
        .module('app', ['ui.router'])
        .config(configure);

    function configure($stateProvider, $urlRouterProvider) {

        $urlRouterProvider.otherwise('/login');

        $stateProvider.state('login', {
            url : '/login',
            templateUrl : 'login.html',
            controller : function ($scope, $http, $state, $rootScope){

                //login functionality.
                $scope.login = function(){
                    if ($scope.formdata.username != "" && $scope.formdata.password != "")
                    {
                        $http.post('/login', $scope.formdata)
                        .success(function (data){
                            console.log(data)
                            if (data.loginFlag){
                                $state.go('main')
                            }
                        })
                        .error(function (data){
                            console.log("Error", data)
                        });
                    } else {

                    }
                }

                //changing state to signup
                $scope.goToSignUp = function(){
                    $state.go('signup')
                }
            }
        })

        .state('signup',{
            url: '/signup',
            templateUrl: 'signup.html',
            controller: function ($scope, $http, $state){

                //changing state to login
                $scope.goBackToSign = function(){
                    $state.go('login')
                }
            }
        })

        .state('main',{
            url: '/main',
            templateUrl: 'main.html',
            //inject menuUtil so that you can use below on controller
            resolve: {
                menuUtil: 'menuUtil'
            },
            controller: function ($scope, $http, $state, menuUtil){

                $scope.menuUtil = menuUtil;

                //toggle class for menu display/no display
                $scope.toggleMenu = function() {
                    menuUtil.toggle = !menuUtil.toggle;
                };
            }
        });
    }
})();

我添加了app.controller.js,以便您可以在ui-view之外访问工厂 app.controller.js:

(function () {
    'use strict';

    angular
        .module('app')
        .controller('AppController', AppController);

    AppController.$inject = ['$scope', 'menuUtil'];
    function AppController ($scope, menuUtil) {
        $scope.menuUtil = menuUtil;
    }

})();

并且还添加了工厂,以便在您的应用中将此菜单信息提供给您需要的位置 menuUtil.js:

(function () {
    'use strict';

    angular
        .module('app')
        .factory('menuUtil', menuUtil);

    function menuUtil () {
        var toggle = true;
        var showMenu = true;
        var showMenuBtn = true;

        var service = {
            showMenu: showMenu,
            showMenuBtn: showMenuBtn,
            toggle: toggle
        };

        return service;
    }

})();

正如您所看到的,我对样式做了一些更改,但它仍然可以更好。不要做代码,做得很漂亮hehe:D GL希望我帮助

答案 2 :(得分:0)

看起来你错放了一个支架。

而不是

angular.element($('#wrapper').toggleClass('toggled'));

尝试

angular.element(document.getElementById(wrapper)).toggleClass('toggled');

答案 3 :(得分:0)

您尝试过使用ng-class吗?

<div id="page-content-wrapper" ng-class="{ 'toggled': isToggled }">

然后在你的控制器中:

$scope.isToggled = false;
$scope.toggleMenu = function() {
    $scope.isToggled = !$scope.isToggled;
}

https://scotch.io/tutorials/the-many-ways-to-use-ngclass

答案 4 :(得分:0)

您必须将我们的按钮放在ui-view中才能使其正常工作,尽管它不是正确的路由方式。

   <div ui-view>
            <button type="button" id="menu-toggle" class="btn btn-primary" ng-click="toggleMenu()" ng-show="showMenuBtn">Menu</button>
   </div>

更新:请参阅我为您创建的plunker,了解如何通过正确的路由完成工作。

http://plnkr.co/edit/1sRSWcG2JInyvSEiSOJ8?p=preview