角度 - 可重用的对话框

时间:2013-02-24 03:40:48

标签: angularjs angularjs-directive

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

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

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

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

3 个答案:

答案 0 :(得分:6)

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

  1. 为对话框创建服务
  2. 创建指令并将服务注入其中。执行链接功能时,将$ scope.dialogData之类的内容传递给服务,以便服务可以更新数据。
  3. 创建一个获取注入服务的控制器。通过服务设置对话框数据以显示对话框。由于您正在修改指令范围内的控制器中的数据,因此Angular会注意到并更新您的对话框。
  4. 在对话框包装器上添加ng-show,以便在服务上实现open()/ close()方法变得简单。
  5. 现在您有一个可以在系统中的任何位置使用的对话框,您只需重复使用相同的指令,而不必乱用DOM或编译。

答案 1 :(得分:5)

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

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

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

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

可以在此插件中看到:http://plnkr.co/edit/PG0iHG?p=preview

答案 2 :(得分:2)

我认为很好的问题。你想知道是否可以“热交换”元素的范围。我不知道是否有办法做到这一点,或者即使有,如果这是Angular方式。我接受你看看ng-view如何得到你所得到的效果?

我的建议是进行一次$ compile,保留结果,链接或转换函数或者在Angular用语中调用的任何内容。并为每个所需的对话实例调用它。