假设我在父控制器中放置一个 Bootstrap 风格的 alert 框,用于提示错误,类似如下效果: !()[https://ww1.sinaimg.cn/large/006tKfTcjw1fbrff61vqcj308q03pglq.jpg]
<body ng-controller="ParentController as parentCtrl">
<!-- 这里有一个 alert ,用于显示错误 -->
<div ng-show="parentCtrl.alert"></div>
<div ng-controller="ChildController as childCtrl">
</div>
</body>
在 js 文件中,我在控制器 ParentController
中定义了变量 alert
:
app.controller('ParentController', [function() {
var self = this;
self.alert = null;
}]);
app.controller('ChildController', [function() {
// 那么这里应该如何访问到 ParentController 中的 alert 呢?
}]);
现在我想做的,是当 ChildController
中某些操作出现错误的时候,给 ParentController
中的 alert
赋值,这样那个错误 alert 框就可以显示,不知道应该如何写 ChildController
的代码呢?
现在有一个折中的办法是,将 ParentController
中的 alert
元素绑定到 $scope
中,即如下:
<body ng-controller="ParentController as parentCtrl">
<!-- 这里有一个 alert ,用于显示错误 -->
<div ng-show="alert"></div>
<div ng-controller="ChildController as childCtrl">
</div>
</body>
相应的 js 文件如下:
app.controller('ParentController', ['$scope', function($scope) {
$scope.alert = null;
}]);
app.controller('ChildController', ['$scope', function($scope) {
$scope.alert = {
type: 'alert',
info: 'Error...'
};
}]);
但是现在的 AngularJS 不都推崇的是直接将要显示的数据绑定到控制器上,而不是向控制器中注入 $scope
变量。因此想请教一下大家正确的方法,或者是在单页面应用中,如何正确地显示错误框。
1
alibabamama 2017-01-15 20:00:42 +08:00
我也又遇到过类似的问题,用的`yeoman`生成的一套系统,所以整个架构和写法上和你贴出来的有点不同。我在 child state 通过$scope, 类似 `$scope.ParentController.alert`的形式去获取和更新的。
|
2
gyteng 2017-01-15 20:46:51 +08:00
绑定到$scope 是一种方法,还可以自己写一个 service 来搞定多个 controller 之间共享数据的问题
|
3
tianshilei1992 OP @gyteng 诶?写给 service 如何来共享数据呀?我能想到的只是单向传递,如果 service 里面的值变了,如何保证 controller 的值也跟着改变呀?😄
|
4
WittBulter 2017-01-16 07:39:30 +08:00 via iPhone
手机写了一堆,忘了保存,待会换电脑来写。
|
5
WittBulter 2017-01-16 16:21:30 +08:00 2
这是典型的父子通信问题,但是并不符合你的业务逻辑。
在 NG1 中,如果真的要使用父子通信,最优雅的办法是采用一个共享的服务来解决,当有涉及模板时,应创建一个指令,任何子控制器都通过相应的事件来触发指令。使用共享作用域的 scope 的方法实际上不好的,你代码中的父级作用域其实就是类似 rootScope ,当他们被越来越多的变量、对象占有时,很难通过控制器之间的切换累释放内存。其次当你需要调用他们的时候也会很难,特别是你的控制器代码被复用时,其他人很难知道需要在父级再做一件这样的事。这就违背了 NG1 中自治的哲学。 如果要达到这一点,至少要保证你的任何控制器不依赖于其他控制器,任何指令可以直接使用而无需在控制器中为它准备一些元数据,任何服务也是注入即使用。这其实是很难的,因为你要做一些额外的工作来达到这一点,比如强制自己不使用非当前作用域的变量、函数,通信采用服务与事件等等。但是它们带来的好处也显而易见。 业务逻辑中, Alert 这样的问题常常会带有一个基础的模板,我建议是将它包装成一个指令,使用 Alert 相应模板,然后在较高层作用域的模板中编译(让子作用域都可以享受),当你需要它显示时,在控制器中发出相应的事件来触发这个模板显示与隐藏。 还有一种更优雅的解决方案,新建一个 alertModule ,将控制器、指令、服务全部挂载在 alertModule 上,再让业务的 module 依赖它,即可以使用相应的方法来触发这个弹窗模块。 你可以参考一下我写的两个模板,它们分别是挂载 window 和挂载 module 方式。 https://github.com/WittBulter/sendAlert https://github.com/WittBulter/angular-mobile-tips angular-mobile-tips 使用了很多有意思的技巧,是一个典型的 NG1 插件,可以尝试模仿它写一个。 |
6
tianshilei1992 OP @WittBulter 非常感谢,我先研究一下你给的那两个模版。
|