从指令访问控制器范围 [英] Access controller scope from directive

查看:27
本文介绍了从指令访问控制器范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个简单的指令,用于显示我正在创建的

的排序列标题.

I've created a simple directive that displays sort column headers for a <table> I'm creating.

ngGrid.directive("sortColumn", function() {
    return {
        restrict: "E",
        replace: true,
        transclude: true,
        scope: {
            sortby: "@",
            onsort: "="
        },
        template: "<span><a href='#' ng-click='sort()' ng-transclude></a></span>",
        link: function(scope, element, attrs) {
            scope.sort = function () {

                // I want to call CONTROLLER.onSort here, but how do I access the controller scope?...
                scope.controllerOnSort(scope.sortby);
            };
        }
    };
});

以下是正在创建的一些表头的示例:

Here's an example of some table headers being created:

<table id="mainGrid" ng-controller="GridCtrl>
<thead>
    <tr>
        <th><sort-column sortby="Name">Name</sort-column></th>
        <th><sort-column sortby="DateCreated">Date Created</sort-column></th>
        <th>Hi</th>
    </tr>
</thead>

因此,当单击排序列时,我想在我的网格控制器上触发 onControllerSort 函数......但我被卡住了!到目前为止,我能够做到这一点的唯一方法是为每个 <sort-column> 添加onSort"的属性并在指令中引用这些属性:

So when the sort column is clicked I want to fire the onControllerSort function on my grid controller.. but I'm stuck! So far the only way I've been able to do this is for each <sort-column>, add attributes for the "onSort" and reference those in the directive:

<sort-column onSort="controllerOnSort" sortby="Name">Name</sort-column>

但这不是很好,因为我总是想调用controllerOnSort,所以为每个指令插入它有点难看.如何在指令中执行此操作而不需要在我的 HTML 中进行不必要的标记?如果有帮助,指令和控制器都定义在同一个模块中.

But that's not very nice since I ALWAYS want to call controllerOnSort, so plumbing it in for every directive is a bit ugly. How can I do this within the directive without requiring unnecesary markup in my HTML? Both the directive and controller are defined within the same module if that helps.

推荐答案

创建第二个指令作为包装器:

Create a second directive as a wrapper:

ngGrid.directive("columnwrapper", function() {
  return {
    restrict: "E",
    scope: {
      onsort: '='
    }
  };
});

然后你可以只在外部指令中引用要调用一次的函数:

Then you can just reference the function to call once in the outer directive:

<columnwrapper onsort="controllerOnSort">
  <sort-column sortby="Name">Name</sort-column>
  <sort-column sortby="DateCreated">Date Created</sort-column>
</columnwrapper>

在sortColumn"指令中,您可以通过调用来调用引用的函数

In the "sortColumn" directive you can then call that referenced function by calling

scope.$parent.onsort();

请参阅此小提琴以获取工作示例:http://jsfiddle.net/wZrjQ/1/

See this fiddle for a working example: http://jsfiddle.net/wZrjQ/1/

当然,如果您不关心具有硬编码的依赖项,您也可以保留一个指令,并通过

Of course if you don't care about having hardcoded dependencies, you could also stay with one directive and just call the function on the parent scope (that would then be the controller in question) through

scope.$parent.controllerOnSort():

我有另一个小提琴显示这个:http://jsfiddle.net/wZrjQ/2

I have another fiddle showing this: http://jsfiddle.net/wZrjQ/2

此解决方案与其他答案中的解决方案具有相同的效果(对硬耦合具有相同的批评) (https://stackoverflow.com/a/19385937/2572897)但至少比该解决方案容易一些.如果无论如何你都很难结合,我认为引用控制器没有意义,因为它很可能一直在 $scope.$parent 上可用(但要注意设置范围的其他元素).

This solution would have the same effect (with the same criticism in regard to hard-coupling) as the solution in the other answer (https://stackoverflow.com/a/19385937/2572897) but is at least somewhat easier than that solution. If you couple hard anyway, i don't think there is a point in referencing the controller as it would most likely be available at $scope.$parent all the time (but beware of other elements setting up a scope).

不过,我会选择第一个解决方案.它添加了一些小标记,但解决了问题并保持了清晰的分离.如果您使用第二个指令作为直接包装器,您也可以确保 $scope.$parent 匹配外部指令.

I would go for the first solution, though. It adds some little markup but solves the problem and maintains a clean separation. Also you could be sure that $scope.$parent matches the outer directive if you use the second directive as a direct wrapper.

这篇关于从指令访问控制器范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆