AngularJS:如何嵌入并同时拥有隔离范围和父范围? [英] AngularJS : How to transclude and have both isolate scope and parent scope?

查看:24
本文介绍了AngularJS:如何嵌入并同时拥有隔离范围和父范围?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模式,其中许多项目类型都是可编辑的".这意味着我有很多模板(每个可编辑项目类型一个),它们希望具有独特的字段,但具有通用功能(编辑、保存、取消编辑、删除等).这些常用函数会导致控制器上出现大量重复:saveeditcancel 等,以及非常重复的错误处理.

我认为处理这个问题的一种方法是让每个控制器装饰"自己(使用服务),但它也会变得混乱.

我更喜欢一个指令,比如可编辑":

<div ng-show="editMode"><!-- 很多字段,例如--><input type="text" ng-model="name"></input><span ng-show="editGroup.name.$error.required">名称为必填项</span><button type="submit" ng-click="save()">保存</button><button ng-click="cancel">取消</button>

<div ng-show="!editMode"><!-- 大量文本,例如--><span>{{name}}</span><button ng-click="edit()">编辑</button><button ng-click="delete()">删除</button>

</表单>

问题是所有模型都来自 controller 作用域,因为它们是这个模板独有的,而重复作用域项,如函数 save() cancel() edit() delete() 都来自指令隔离作用域.

我是,嗯,混合范围,当然我无法提前知道需要提供哪些项目.因此,如果我使用以下内容进行嵌入:

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

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

解决方案

我设法通过避开 ng-transclude 并在链接函数中做我自己的嵌入来解决这个问题.

以下相当于普通的ng-transclude:

link: function (scope,element,attrs,ctrlr,transclude) {var sc = scope.$parent.$new();transclude(sc,function(clone,scope){element.append(克隆);//或者你想操作DOM});}

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

link: function (scope,element,attrs,ctrlr,transclude) {var sc = scope.$parent.$new();sc.editMode = false;sc.save = function() {};sc.edit = 函数 () {sc.editMode = true;};//等等.transclude(sc,function(clone,scope){element.append(克隆);//或者你想操作DOM});}

两全其美!

I have a pattern wherein many item types are "editable". This means that I have lots of templates (one for each editable item type) that expect to have unique fields, but common functions (edit, save, cancel edit, delete, etc.). These common functions lead to lots of repetition on controllers: save, edit, cancel, etc., and very repetitive error-handling.

One way I looked at of dealing with this was to have each controller "decorate" itself (using a service), but it got messy as well.

I prefer a directive, say, '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>

The problem is that all of the models come from the controller scope, since they are unique to this template, while the repetitive scope items, like the functions save() cancel() edit() delete() all come from the directive isolate scope.

I am, well, mixing scopes, and of course I have no way of knowing in advance what items need to be available. So if I transclude with:

  • isolate scope: I lose access to the controller models in the transcluded element, as well as the form for validations
  • controller scope (default): I lose access to the added on functions from the directive, which was the point of the directive in the first place!

I am doing something wrong here; what is the better (cleaner?) way to do this?

解决方案

I managed to figure it out by shying away from ng-transclude and doing my own transclusion in the link function.

The following is the equivalent of the normal 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
   });
}

By adding the functions directly onto the transclude child scope, I was able to have everything work, without messing with the parent scope, which I really didn't want to do.

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
   });
}

Best of both worlds!

这篇关于AngularJS:如何嵌入并同时拥有隔离范围和父范围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆