22

任务:

  • 显示联系方式。
  • 联系人是 JSON 数据,比如说 {name: "Mark", location: "England", phone: [...]}。
  • 联系人可以以多种方式显示:紧凑/详细/使用附加信息增强(共享联系人 - 附加指令)

因为联系人可以显示在不同位置的不同页面上,所以很自然地为联系人创建指令(小部件),但这里有一个问题:“如何使用多个模板组织同一个小部件?”

选项:

  1. 使用一个模板创建一个指令,根据联系人“类型”隐藏部分-可能有很多 ng-switch 和 ng-if 的大模板
  2. 为每个模板创建指令-几乎相同的指令,只有不同的模板(或 templateURL)
  3. 链接时动态加载模板-包含和替换(合并属性)有问题

你解决这些问题的经验是什么?

4

2 回答 2

19

我个人认为选项 2 提供了显示模式之间的清晰分离。我创建了一个有效的 CodePen 示例来说明如何通过为每个模板使用单独的指令来干净地完成此操作。

我在 CodePen 示例中使用的方法利用了一个模板工厂,该工厂通过 Angular DI 注入到每个指令中。模板工厂实现非常简洁,因为它只为每种不同的支持显示模式(紧凑和详细)使用ng-include模板字符串。实际的 HTML 模板(部分)可以存放在外部视图文件或内部脚本块中。

使用联系指令很容易:

<contact compact ng-repeat="contact in contacts" ng-model="contact"></contact>

这将创建联系人列表的紧凑版本。

<contact detailed ng-repeat="contact in contacts" ng-model="contact"></contact>

这将创建一个详细的联系人列表。

我承认我还没有将这样的代码部署到生产环境中,因此可能存在我没有考虑到的可扩展性或其他问题。我希望我提供的代码能够回答您的问题,或者至少为进一步探索提供灵感。

于 2013-09-26T03:08:09.820 回答
12

我已经建立了一种处理 Adam 示例的新方法,并且还使用了 angular 文档中的示例,他们在其中讨论了 templateUrl 属性https://docs.angularjs.org/guide/directive中的函数,这是来自 angular 文档的 plunker:http ://plnkr.co/edit/h2CSf2WqCLYfPvzL9WQn?p=preview

.directive('myCustomer', function() {
    return {
      templateUrl: function(elem, attr){
        return 'customer-'+attr.type+'.html';
      }
    };
  });

这是我的混合解决方案:

http://codepen.io/anon/pen/wawOyz?editors=101

app.factory('templates', function() {
  return {
    compact:   'compact',
    detailed:  'detailed'
  };
 });

app.directive('contact', function(templates) {
  return {
    restrict: 'E',
    templateUrl: function($elem, $attr){
      return templates[$attr.mode];       
    },
    scope: {
      contact: '=ngModel'
    }
  };
});

我喜欢在一个工厂中拥有所有模板地址的想法,但我发现每个模式的指令非常重复,如果您有多个使用这种方法的元素,您将需要命名它们(联系人文本、电子邮件文本、公司文本) 所以他们不会崩溃。

我还不确定这是否是一种更好的方法,是否更短更干燥,但可能更难测试或更少可定制。我只是想分享这种方法,以防它可以帮助任何人。

于 2015-04-20T21:34:10.367 回答