6

我需要构建一个对话框以用于项目列表中的任何项目。除了明显依赖于项目的字段值之外,无论项目如何,对话框都几乎相同。

我正在构建的指令是从文件中读取模板,使用 $compile 对其进行编译,然后将其绑定(链接)到项目的范围。绑定的结果是一个 DOM 树。为了使对话框可见,我需要将此树附加到现有 DOM 中的某个元素。我的对话框的性质使得将其直接附加到 body 标记是有意义的。该对话框将与列表中的不同项目组合使用多次

所以这是我的问题:这个过程(编译、绑定、追加)有多少可以提前完成?我当然可以运行编译一次。我还可以将编译结果绑定到 $rootscope 并将其附加(隐藏)到 body 标记。这样我以后可以打开可见性并显示对话框。

但是,如果它已经绑定并附加到 DOM,是否可以将其重新绑定到其他范围,如果是,那么正确的方法是什么?另一个问题是它是否值得?可能只是在每次需要时重新插入它?

4

3 回答 3

6

如果您一次只显示一个这样的对话框并且您会经常使用它,则不必将其重新绑定到另一个范围,只需更改范围上的数据即可。像这样的东西:

  1. 为您的对话创建服务
  2. 创建指令并将您的服务注入其中。当链接函数执行时,将类似 $scope.dialogData 的内容传递给服务,以便服务可以更新数据。
  3. 创建一个控制器来注入服务。通过服务设置对话数据以显示对话。由于您正在修改指令范围内的控制器中的数据,因此 Angular 会注意到并更新您的对话框。
  4. 在您的对话框包装器上添加 ng-show 以简化在您的服务上实现 open()/close() 方法。

现在您有了一个可以在系统中的任何位置使用的对话框,并且您只需重新使用相同的指令,而不必弄乱 DOM 或编译。

于 2013-02-24T08:47:09.937 回答
6

这确实是一个很好的问题,我很高兴看到越来越多的人开始将对话视为服务。

关于您的具体问题,以下是我的一些想法:

  • 您可以“缓存”链接函数(即 - 从$compile调用返回的函数),然后根据需要调用此函数(传入范围变量)。
  • 您只能在打开对话框时按需附加它,而不是插入(隐藏)编译元素。最重要的是,我宁愿将模态元素附加到$rootElement而不是<body>仅仅不触及ng-app定义位置上方的 DOM 元素。只是不要触摸 AngularJS 无法控制的 DOM 部分。
  • IMO 对话框非常接近 AngularJS 路由(因为它们提供了不同的“视图”),因此能够在显示模式之前解决承诺会非常好(就像路由一样)。

事实上,在设计一个好的、通用的对话服务时,有很多事情需要考虑,我希望这些建议以及其他人提供的出色输入能够帮助您入门。但这一切都是理论上的,所以如果您正在查看此处讨论的内容的实现,您可以查看此实现(来自http://angular-ui.github.com/bootstrap/的$dialog 服务- 它是完全可定制的,因此可以与 Bootstrap 以外的 CSS 一起使用。此处的文档)。

它可以在这个 plunk 中看到:http ://plnkr.co/edit/PG0iHG?p=preview

于 2013-02-24T12:09:37.253 回答
2

我认为很好的问题。您想知道是否可以“热交换”元素的范围。我不知道是否有办法做到这一点,或者即使有,如果那是 Angular 方式。我认为您查看了ng-view如何达到您的目标?

我的建议是 $compile 一次,将结果、链接或嵌入函数或任何它在 Angular 用语中称为的东西保留在某个地方。并为每个需要的对话框实例调用它。

于 2013-02-24T03:55:05.913 回答