Angularjs 独立的指令范围,没有自己的模板 [英] Angularjs isolated scope for directives without own template

查看:23
本文介绍了Angularjs 独立的指令范围,没有自己的模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在没有自己的模板的情况下在 AngularJS 中创建可重用的指令.我还希望为该指令设置隔离范围.我的方法的最佳实践是什么?为什么我的示例没有按预期工作?

我希望我可以分别从指令编辑 obj1 和 obj2.

HTML:

X1: {{ obj1.x }}, Y1: {{ obj1.y }}X2: {{ obj2.x }}, Y2: {{ obj2.y }}<小时>编辑 obj1:<div draggable target="obj1"><input type="text" ng-model="target.x"><input type="text" ng-model="target.y">

编辑 obj2:<div draggable target="obj2"><input type="text" ng-model="target.x"><input type="text" ng-model="target.y">

JS:

angular.module("App", []).controller("MyCtrl", function($scope) {$scope.obj1 = {x: 10,y:20};$scope.obj2 = {x: 30,y:40};}).directive("draggable", function() {返回 {范围: {目标:="},链接:功能(范围,EL,属性){console.log("作用域:",作用域);}}});

PLUNKR:http://plnkr.co/edit/Dw8IiFVSOZGjSTFGRMzZ

解决方案

你的代码现在的工作方式是,每个指令的内容都绑定到父作用域,而不是指令的独立作用域,所以每个target 是对同一个变量的引用.

您需要做的是transclude 指令的内容.通常的用途是您希望内容在指令的父作用域中,而不是在孤立的作用域中.但是,您希望内容位于指令的隔离范围内.因此,您必须手动调用 transclude 函数,并将内容绑定到指令的隔离范围:

.directive("draggable", function($compile) {返回 {转置:真实,范围: {目标:="},链接:函数(范围,元素,属性,ctrl,transclude){transclude(范围,功能(克隆){element.append(克隆);});}}})

您可以在此 Plunker 中查看此内容.它不做的一件事是 $watch 'target' 的内容,所以我怀疑它不会对指令上的target"属性的变化做出反应.这可能最好留给另一个问题.

transclude 的使用不正确/过于复杂.您可以将 scope 作为第一个参数传入,以将克隆正确绑定到正确的范围.

I want to create reusable directive in AngularJS without own template. I also want to have isolated scope for that directive. What is the best practices for my approach? Why my example doesn't work as I expect?

I expected that I could edit obj1 and obj2 from directives separately.

HTML:

<div ng-controller="MyCtrl">
  X1: {{ obj1.x }}, Y1: {{ obj1.y }}
  X2: {{ obj2.x }}, Y2: {{ obj2.y }}
  <hr>
  Edit obj1: 
  <div draggable target="obj1">
    <input type="text" ng-model="target.x">
    <input type="text" ng-model="target.y">
  </div>
  Edit obj2:
  <div draggable target="obj2">
    <input type="text" ng-model="target.x">
    <input type="text" ng-model="target.y">
  </div>
</div>

JS:

angular.module("App", [])
  .controller("MyCtrl", function($scope) {
    $scope.obj1 = {
      x: 10,
      y: 20
    };
    $scope.obj2 = {
      x: 30,
      y: 40
    };
  })
  .directive("draggable", function() {
    return {
      scope: {
        target: "="
      },
      link: function(scope, el, attrs) {
        console.log("scope: ", scope);
      }
    }
  });

PLUNKR: http://plnkr.co/edit/Dw8IiFVSOZGjSTFGRMzZ

解决方案

The way your code is working now, is that the contents of each directive is bound to the parent scope, and not the isolated scope of the directive, so each target is a reference to the same variable.

What you'll need to do is to transclude the contents of the directive. The usual use for this is that you want the contents to be in the parent scope of the directive, and not in the isolated scope. However, you want the content to be in the isolated scope of the directive. So you'll have to call the transclude function manually, and bind the contents to the isolated scope of the directive:

.directive("draggable", function($compile) {
  return {
    transclude: true,
    scope: {
      target: "="
    },
    link: function(scope, element, attrs, ctrl, transclude) {
      transclude(scope, function(clone) {
       element.append(clone);
      });
    }
  }
})

You can see this in this Plunker. One thing it doesn't do is $watch the contents of the 'target' so I suspect it won't react to changes in the "target" attribute on the directive. This might be best left to another question.

Edit: the use of transclude was incorrect / overcomplicated. You can pass the scope in as the first parameter to properly bind the clone to the correct scope.

这篇关于Angularjs 独立的指令范围,没有自己的模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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