AngularJS自定义指令中ng-click无法触发控制器方法的问题
问题分析与解决方案
首先咱们先揪出最显眼的问题:模块名称不匹配!
你在app.js里创建的Angular模块是mainApp:
var app = angular.module('mainApp',[ 'ui.router' ]);
但你的index.html里指定的根模块是BlurAdmin:
<html lang="en" ng-app="BlurAdmin">
这就导致你写的LoginPageCtrl控制器和loginPage指令全注册到了一个Angular根本不会加载的模块里,相当于这些代码完全没生效,点击按钮自然没反应!
然后第二个问题:指令和控制器没有正确关联。你在路由里给login state指定了LoginPageCtrl,但你的登录页面是通过index里的<login-page>指令渲染的,这个指令并没有和路由的控制器绑定,就算模块对了,指令模板的作用域里也找不到login()方法。
修复步骤
1. 修正模块名称
把app.js里的模块名称改成BlurAdmin,和index里的ng-app保持一致:
var app = angular.module('BlurAdmin',[ 'ui.router' ]);
2. 让指令关联控制器(二选一即可)
方式一:指令内直接指定控制器(推荐)
修改你的loginPage指令定义,加入controller属性,让指令自己绑定控制器:
app.directive('loginPage', function loginPage() { return { restrict: 'EA', templateUrl: 'app/partial/login.html', controller: 'LoginPageCtrl', // 绑定控制器 controllerAs: 'vm' // 可选,用controllerAs语法更清晰,避免作用域混淆 } })
如果用了controllerAs: 'vm',记得把login.html里的ng-click改成:
<button ng-click="vm.login()" type="submit" class="btn btn-default">Sign in</button>
方式二:完善路由配置,让控制器作用到指令
如果你想保留路由指定控制器的方式,需要给login state指定模板,让模板包含你的指令,同时确保路由的视图能正确渲染:
app.config(['$stateProvider', function($stateProvider) { $stateProvider .state('login', { url: '/login', controller: 'LoginPageCtrl', template: '<login-page></login-page>' // 这里指定模板包含指令 }); }])
同时要确保index.html里有ui-router的视图容器,比如加上:
<div ui-view></div>
这样路由渲染时,控制器的作用域会绑定到这个视图容器里的指令,模板里的login()方法就能被找到了。
额外说明
你用指令来区分登录页和用户页的CSS布局思路是没问题的,只要确保模块、指令、控制器的关联正确,就能正常工作啦。
内容的提问来源于stack exchange,提问作者Toni
相关产品推荐
相关产品推荐

