【问题标题】:Angular Scope within Directives指令中的角度范围
【发布时间】:2013-09-30 02:29:10
【问题描述】:

鉴于 JQuery UI 按钮的这个相当简单的角度包装器:

angular.module('Sample.controllers', [])
  .controller('mainController', ['$scope',
    function($scope) {
      $scope.jump =  function () {alert("jump");};
   }])
  .directive('jquiwButton', function() {
    return {
      scope: {},
      restrict: 'A',
      replace:true,
      link: function(scope, element, attrs) {
        var options = {};
        if (angular.isDefined(attrs["jquiDisabled"])) {
          options.disabled = attrs["jquiDisabled"];
        }

        if (angular.isDefined(attrs["jquiIconPrimary"])) {
          if (!angular.isDefined(options.icons.primary)) {
            options.icons ={};
          }
          options.icons.primary = attrs["jquiIconPrimary"];
        }

        if (angular.isDefined(attrs["jquiIconSecondary"])) {
          if (!angular.isDefined(options.icons.secondary)) {
            options.icons ={};
          }
          options.icons.secondary = attrs["jquiIconSecondary"];
        }

        if (angular.isDefined(attrs["jquiLabel"])) {
          options.label = attrs["jquiLabel"];
        }

        if (angular.isDefined(attrs["jquiText"])) {
          options.text = attrs["jquiText"];
        }

        element.button(options);
      }
    };
  });
  angular.module('Sample', ['Sample.controllers']);  

还有标记。

<body ng-controller="mainController"> 
  <button jquiw-button jqui-label="Hello" ng-click="jump()">Hello</button>
</body>

它工作正常,直到我添加一个范围,此时我失去了使用标准角度绑定到外部范围的能力。在我的情况下,标记 `ng-click='jump()' 现在将不起作用,因为它找不到在外部上下文中定义而不是在隔离范围中定义的方法 jump。现在我知道我可以专门将 ng-click 绑定回外部范围,但我想避免这样做,因为它需要了解我可能需要绑定的所有可能指令。

所以我的问题是:如何让其他指令在外部范围内工作,同时仍然具有隔离范围?

plunker:http://plnkr.co/edit/eRoOeq?p=preview

删除第 8 行:scope: {},,它会 ng-click 调用正确的函数。

【问题讨论】:

  • 我认为不可能做到这一点......还是看看ng-repeat是如何实现的......

标签: angularjs angularjs-directive


【解决方案1】:

使用ng-click="$parent.jump()"

【讨论】:

  • 这行得通,但似乎不优雅。有没有更好的方式来表达“对于我没有在我的范围内定义的所有东西,让它在外部范围内”?
  • 它有效。除非您有意隔离,否则使用范围似乎不是一个好主意。我想这是有道理的。
【解决方案2】:

您可以使用&amp; 绑定从隔离范围内引用父范围内的函数。这是从指令according to the directive documentation 内的隔离作用域调用函数的正确方法。

我创建了一个working CodePen example 来证明它可以完美运行。

以下是相关部分:

var app = angular.module('app', []);

app.controller('MainCtrl', function($scope) {
  $scope.jump = function() {
    alert('jump called');
  };
});

app.directive('myDirective', function() {
  return {
    restrict: 'E',
    scope: {
      call: '&'
    },
    link: function postLink(scope, element, attrs) {
      scope.call();
    }
  };
});

在模板中:

<section ng-app="app" ng-controller="MainCtrl">
  <my-directive call="jump()"></my-directive>
</section>

我希望这会有所帮助。

【讨论】:

  • 但这不需要高级知识和那些外部指令的映射吗?换句话说,我可能不知道用户要绑定 ng-blur 或 ng-change,所以这种方法需要我对所有可能的绑定有先见之明,然后手动绑定它们。
  • 如果我正确理解了您的问题,您正在担心一些不应该发生的事情。如果您正在创建一个全新的指令,那么您就是在指定用法。如果另一个开发人员在没有查阅指令文档的情况下将ng-clickng-blur 放在您的元素上,那么他们就是在冒险。您的新指令的潜在用户应该知道您的指令使用特定属性。
  • 我想这是对的,但它仍然要求我为每个指令编写绑定代码,即使我没有做指令通常会做的事情——这很可能是一个设计特性和答案是“不要使用你自己的范围,除非你想将你的指令与这种事情完全隔离开来。”似乎是这样。似乎隔离范围确实是隔离。
  • 这实际上是一个很好的问题。我想知道关于在我们的自定义指令上通过本机 ng-* 指令而不在隔离范围内显式绑定它们的同样事情。我发现即使在本机角度指令中,它们也不总是很好地放在一起。这使我相信严格遵守规定的用法。这进一步让我相信,指定使用我们自己的自定义指令是可以接受的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-04
  • 1970-01-01
  • 1970-01-01
  • 2013-10-07
  • 1970-01-01
  • 2015-08-20
  • 1970-01-01
相关资源
最近更新 更多