在angularJS应用程序中跟踪UI状态

时间:2014-04-15 20:22:04

标签: angularjs angularjs-scope angular-ui

说明: 我正在使用ui-router在Web应用程序上工作,并使用嵌套的视图/控制器。应用程序中有几个需要通信的UI元素,以及哪些操作可能依赖于另一个人的状态。

示例: 例如,我有一个"下拉"功能类似于典型下拉菜单的元素。 A"下拉"可以存在于任何控制器中,但在任何给定时间只能打开一个。也就是说,如果用户打开下拉菜单,它还应该关闭所有其他下拉菜单。

提议的解决方案: 我目前的解决方案是在"下拉"单击,在最顶层的父控制器中监听它,并$ even一个偶数来关闭所有下拉列表,然后在每个其他控制器中捕获该事件。

还有其他要素跟踪的元素,例如主侧边栏(展开或折叠),以及更复杂的事件数组(屏幕大小,点击侧边栏中的项目,点击在一个"菜单"按钮上)看起来......看起来很麻烦。

TL; DR: 是否是跨控制器将UI元素状态(可见/不可见,扩展/折叠)传递给$ emit和$ broadcast事件的标准方法?

编辑: 我想到的另一个选择是在子控制器中创建一个$ watch来跟踪全局的“ui元素状态”。最顶层父控制器中的变量。类似于我上面描述的,但没有$ broadcast。

2 个答案:

答案 0 :(得分:1)

我认为你走的是正确的轨道。我并不是在各处投掷赛事的狂热粉丝所以我希望尽可能避免它。您可以做的一件事是尝试挂钩浏览器的内置事件。例如,使用下拉示例,您可以只收听document.click事件并在单击文档时隐藏下拉列表,而不是用户打开另一个下拉列表。

无论如何,我建议的另一件事是确保当你发出事件或听它时,写出完整的字符串而不是构建它。例如:

不要这样做:

var postEventBase = 'post.';
$rootScope.$on(postEventBase + 'created', function() {});
$rootScope.$on(postEventBase + 'deleted', function() {});
$rootScope.$on(postEventBase + 'updated', function() {});

改为

$rootScope.$on('post.created', function() {});
$rootScope.$on('post.deleted', function() {});
$rootScope.$on('post.updated', function() {});

因为事件无处不在的真正问题之一就是当事情变得依赖于事件或对事件作出反应时,你会发现事情没有发生。你需要做到这一点才能让它变得更加强大。只是关于事件的一般提示。它会帮助你避免做噩梦。

无论如何,就你的哲学问题而言,我认为在必要时,使用事件是一种很好的方法来解码代码,同时仍然在整个应用程序中进行通信。小心吧。

答案 1 :(得分:0)

经验和新的最佳实践使我找到了不同的解决方案:

多年后,我终于通过致力于广播活动的服务解决了这个问题。而不是在任何地方使用$ rootScope,而是使用$ inject注入并使用它。

然后,此服务可以将自定义事件发送到任何侦听控制器,从而允许您基于关闭菜单。

我还使用全局点击事件监听器解决了这个问题。每个下拉列表都会创建一个侦听器,如果它注意到其元素的$ scope之外的单击,它将自行关闭。