AngularJS:如何转换并同时隔离范围和父范围?

时间:2015-01-04 13:21:29

标签: angularjs angularjs-directive angularjs-scope angularjs-ng-transclude

我有一种模式,其中许多项目类型是“可编辑的”。这意味着我有许多模板(每个可编辑项类型一个),期望具有唯一的字段,但常见的功能(编辑,保存,取消编辑,删除等)。这些常见功能导致控制器上的大量重复:saveeditcancel等,以及非常重复的错误处理。

我看待处理这个问题的一种方法是让每个控制器自己“装饰”(使用服务),但它也变得混乱。

我更喜欢指令,比如'editable':

<form name="editGroup" editable>
   <div ng-show="editMode">
    <!-- lots of fields, e.g. -->
    <input type="text" ng-model="name"></input>
    <span ng-show="editGroup.name.$error.required">The name is required</span>

    <button type="submit" ng-click="save()">Save</button>
    <button ng-click="cancel">Cancel</button>
   </div>
   <div ng-show="!editMode">
    <!-- lots of text, e.g. -->
    <span>{{name}}</span>

    <button ng-click="edit()">Edit</button>
    <button ng-click="delete()">Delete</button>
   </div>
</form>

问题是所有模型都来自 controller 范围,因为它们对于此模板是唯一的,而重复的范围项,如函数save() {{1} } cancel() edit()都来自指令隔离范围。

我很好,混合范围,当然我无法事先知道需要提供哪些项目。所以如果我转发:

  • 隔离范围:我无法访问transcluded元素中的控制器模型以及验证表单
  • 控制器范围(默认):我无法访问指令中添加的函数,这首先是指令的重点!

我在这里做错了;这样做的更好(更干净?)的方法是什么?

1 个答案:

答案 0 :(得分:5)

我设法通过回避ng-transclude并在链接功能中进行自己的转换来解决这个问题。

以下是正常ng-transclude

的等效内容
link: function (scope,element,attrs,ctrlr,transclude) {
   var sc = scope.$parent.$new();
   transclude(sc,function(clone,scope) {
      element.append(clone); // or however else you want to manipulate the DOM
   });
}

通过直接将函数添加到transclude子范围,我能够让一切正常工作,而不会弄乱父范围,我真的不想这样做。

link: function (scope,element,attrs,ctrlr,transclude) {
   var sc = scope.$parent.$new();
   sc.editMode = false;
   sc.save = function() {
   };
   sc.edit = function () {
     sc.editMode = true;
   };
   // etc.
   transclude(sc,function(clone,scope) {
      element.append(clone); // or however else you want to manipulate the DOM
   });
}

两全其美!