6

我有一个 AngularJS 单页应用程序,显示 3 个视图(实际上是 3 个指令)。为了说明我的问题,假设我的 UI 与 GMail 的 UI 相同,并且我的 3 个视图是:

  • 导航窗格(左)——GMail 在其中显示“收件箱”、“草稿”等文件夹...
  • 工具栏(右上角)——GMail 显示按钮的地方
  • 内容窗格(右下)——GMail 显示消息的地方

每当路径发生变化时,这 3 个视图都需要自行更新。例如:

  • 导航窗格需要突出显示特定项目。
  • 工具栏需要显示/隐藏某些按钮。
  • 内容窗格需要从服务器加载和显示特定数据。

在 AngularJS 中执行此操作的最佳方法是什么?

到目前为止,我有:

  1. 排除了使用$routeProvider.when()因为我需要更新三个视图,并且$routeProvider只支持一个ngView
  2. 创建了一个监视当前路径的服务,并使用$rootScope.$broadcast()警告控制器路径已更改。
  3. (或者,代替#2)创建了一个与#2 相同的控制器。
  4. 使用$scope.$on()捕获由 #2 或 #3 广播的事件(我在视图控制器中执行此操作)。

这种作品,但我有几个问题:

  • “路径更改”事件通常在我的事件侦听器到位之前广播,尤其是在初始页面加载时。这可能是因为我的视图模板是从服务器加载的,并且在模板完成加载之前无法设置侦听器。
  • 难道没有更有效/自动化的方式来观察 AngularJS 中的路径变化吗?(见下面我的代码,它看起来很“手动”。)
  • 监视路径更改的代码属于 SERVICE 还是 CONTROLLER?(我倾向于服务,因为控制器更多的是向视图添加行为。)
  • 如何保证我的观点会捕捉到“路径改变”事件?我应该使用一个事件吗?(也许我可以将路径存储在服务中,并让我的视图改为观看服务?)

我观察路径变化的代码(我把它放在服务或控制器中):

var watchExpression = function() { return $location.path(); };
var listener = function(newPath, oldPath) {
    // Broadcast event on $rootScope
    $rootScope.$broadcast('PathChanged', newPath);
};
$rootScope.$watch(watchExpression, listener);

然后,在视图控制器中,我捕捉到事件:

$scope.$on('PathChanged', function(event, path) {
    // Update view based on new path.
});

任何帮助表示赞赏。谢谢。

4

1 回答 1

5

您的最终版本似乎与 locationChangeSuccess 很好,但对于其他阅读本文的人,我认为您太快排除了 $routeProvider。您可以为随路径更改的主内容窗格设置一个 ng-view,然后为导航窗格和工具栏设置其他独立(“静态”)控制器/模板。

现在来听听其他 2 个控制器中的路由变化:

$rootScope.$on('$routeChangeSuccess', function(evt, cur, prev) {
    ...do what you have to do here, maybe set a $rootScope.path as you did
})

全部使用原生 Angular 功能。我实际上是在http://provok.in中执行此操作的,这是我使用 Angular 构建的一个网站,并且我有类似的布局(嗯,不完全是,但我有“静态”部分和主要内容的 ng-view,动态由 routeProvider 根据路径更新)。

于 2012-08-11T00:42:45.340 回答