如何从 AngularJS 中的多级指令获取控制器范围(没有 $parent) [英] How to get controller scope from multi-level directives in AngularJS(without $parent)

查看:24
本文介绍了如何从 AngularJS 中的多级指令获取控制器范围(没有 $parent)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从以下结构的多级指令访问控制器范围:

我创建了一个包含多级作用域的指令.

 1. 控制器作用域1.2.指令1范围(主指令)1.2.1.指令 2 范围1.2.1.1 指令 3 范围

我想从指令 3 中获取控制器范围.

请不要引用 $parent 因为它不确定父级别,用户可能会在另一个指令中使用此指令.(见下面的代码)

<自定义目录><目录1><dir2><dir3></dir1><自定义目录>

用户在测试控制器中创建一个函数,该函数将在我的指令 3 范围内调用(如何获得控制器范围?).

<目录1><dir2><dir3></dir1>

更多细节(请不要参考语法错误):

控制器是:

App.controller('ScopeController', function ($scope, $rootScope, $uibModal, $http, $filter, $cookieStore, Common, $cookies) {$scope.runTest = 函数 () {return `<input type='button' ng-click='testHtml()' value='Test'/>`;}$scope.testHtml = 函数 () {警报(工作");}$scope.model=someModel;$scope.config=someConfig;$scope.columns={html: $scope.runTest};});

dir1 指令:

App.directive("dir1", function ($compile, $filter, $rootScope, $timeout, Common, $window, $http) {返回 {限制:E",优先级:1,终端:假,templateUrl: "Content/html/Table.html?version=2.6",范围: {型号:=",列:=",配置:=",搜索: "@",},链接:函数(范围,元素,属性){scope.CallFunc = 函数(html){if (typeof (html) =="function" )返回 html();别的 {return scope.$parent.$eval(html + "()", {});}}}}});

动态指令编译 runTest 输出

App.directive('dynamic', function ($compile) {返回 {限制:'A',替换:真,链接:函数(范围、元素、属性){scope.$watch(attrs.dynamic, 函数 (html) {ele.html(html);$compile(ele.contents())(scope);});}};});

如果我将行 $compile(ele.contents())(scope); 更改为 $compile(ele.contents())(scope.$parent.$parent); 它的工作.

在这个指令中,我需要在没有 $parent 的情况下获取控制器范围,因为一些用户可能会在另一个与下面相同的指令中使用这个指令:

<dir1 model="model" columns="columns" config="config"><div dynamic="CallFunc(columns.html)"></div></dir1></custom-dir>

使用 HTML 标签

<div dynamic="CallFunc(columns.html)"></div></dir1>

解决方案

此问题处理代码如下:

用于存储控制器范围的服务:

App.service('TableService', function () {返回 {我的范围:空};});

将 TableService 注入动态指令(该指令编译动态内容):

App.directive('dynamic', function ($compile,TableService) {返回 {限制:'A',替换:真,链接:函数(范围、元素、属性){scope.$watch(attrs.dynamic, 函数 (html) {ele.html(html);$compile(ele.contents())(TableService.MyScope);});}};});

最后在控制器中:

App.controller('ScopeController', function ($scope, $rootScope, $uibModal,$http, $filter, $cookieStore, Common, $cookies,TableService) {TableService.myScope = $scope;$scope.runTest = 函数 () {return `<input type='button' ng-click='testHtml()' value='Test'/>`;}$scope.testHtml = 函数 () {警报(工作");}$scope.model=someModel;$scope.config=someConfig;$scope.columns={html: $scope.runTest};});

之后,动态指令可以访问控制器范围,并且即使指令放入另一个指令(不使用 $parent),所有动态事件(如 testHtml)也将被调用.

谢谢@shaunhusainhuan feng 给了我一个想法.

How can I access controller scope from multi-level directives in below structure:

I create a directive that has multi-level scopes inside its.

 1. Controller scope
 1.2. Directive1 scope(main directive)
 1.2.1. Directive2 scope
 1.2.1.1 Directive3 scope

I want to get the controller scope from directive 3.

please don't refer to $parent because the parent level it's not certain and a user may use this directive inside another directive.(see below codes)

<div ng-controller="Test">
   <custom-dir>
      <dir1>
         <dir2>
            <dir3>
            </dir3>
          </dir2>
       </dir1>
    <custom-dir>
</div>

The users create a function in the Test controller and the function will be called in my Directive 3 scope(how to get controller scope?).

<div ng-controller="Test">
     <dir1>
         <dir2>
             <dir3>
             </dir3>
         </dir2>
     </dir1>
</div>

More details(please don't refer to syntax error):

The controller is:

App.controller('ScopeController', function ($scope, $rootScope, $uibModal, $http, $filter, $cookieStore, Common, $cookies) {
    $scope.runTest = function () {
        return `<input type='button' ng-click='testHtml()' value='Test'/>`;
    }
    $scope.testHtml = function () {
        alert("work");
    }
    $scope.model=someModel;
    $scope.config=someConfig;
    $scope.columns={html: $scope.runTest};
});

the dir1 directive:

App.directive("dir1", function ($compile, $filter, $rootScope, $timeout, Common, $window, $http) {
    return {
        restrict: "E",
        priority: 1,
        terminal: false,
        templateUrl: "Content/html/Table.html?version=2.6",
        scope: {
            model: "=",
            columns: "=",
            config: "=",
            search: "@",
        },
        link: function (scope, elem, attrs) {
            scope.CallFunc = function (html) {
                if (typeof (html) =="function" )
                    return html();
                else {
                    return scope.$parent.$eval(html + "()", {});
                }
            }
        }
    }
});

the dynamic directive compile the runTest output

App.directive('dynamic', function ($compile) {
    return {
        restrict: 'A',
        replace:true,
        link: function (scope, ele, attrs) {
            scope.$watch(attrs.dynamic, function (html) {
                ele.html(html);
                $compile(ele.contents())(scope);
            });
        }
    };
});

If I change the line $compile(ele.contents())(scope); to $compile(ele.contents())(scope.$parent.$parent); it's work.

In this directive, I need get the controller scope without $parent because some users may use this directive inside another directive same below:

<custom-dir>
    <dir1 model="model" columns="columns" config="config">
        <div dynamic="CallFunc(columns.html)"></div>
    </dir1>
</custom-dir>

The using HTML tag

<dir1 model="model" columns="columns" config="config">
    <div dynamic="CallFunc(columns.html)"></div>
</dir1>

解决方案

This issue handle with following codes:

A service for storing the controller scope:

App.service('TableService', function () {
        return {
            MyScope: null
        };
    });

Inject the TableService to dynamic directive(this directive compiles dynamic content):

App.directive('dynamic', function ($compile,TableService) {
    return {
        restrict: 'A',
        replace:true,
        link: function (scope, ele, attrs) {
            scope.$watch(attrs.dynamic, function (html) {
                ele.html(html);
                $compile(ele.contents())(TableService.MyScope);
            });
        }
    };
});

And finally in the controller:

App.controller('ScopeController', function ($scope, $rootScope, $uibModal, 
              $http, $filter, $cookieStore, Common, $cookies,TableService) {
    TableService.myScope = $scope;        
    $scope.runTest = function () {
        return `<input type='button' ng-click='testHtml()' value='Test'/>`;
    }
    $scope.testHtml = function () {
        alert("work");
    }
    $scope.model=someModel;
    $scope.config=someConfig;
    $scope.columns={html: $scope.runTest};
});

After that, the dynamic directive can access controller scope and all dynamic events(like testHtml) will be called even if the directive put in another directive(without using the $parent).

thank you @shaunhusain, huan feng for giving me an idea.

这篇关于如何从 AngularJS 中的多级指令获取控制器范围(没有 $parent)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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