在没有$ scope的情况下访问父控制器函数的指令

时间:2015-04-08 13:47:40

标签: javascript angularjs

所以我有这个指令有自己的范围,但我想访问其父控制器内的一个函数。如果父控制器使用$ scope.getElementsList()公开函数,我可以这样做,虽然我试图避免使用$ scope并且我使用self.getElementsList()公开了该函数,并且指令无法访问它

指令:

angular.module('myApp').directive('accountBalance', function() {
  return {
    scope: {
        elementId: '=elementid'
    },
    transclude: true,
    restrict: 'E',
    templateUrl: '../views_directives/account-balance.html',

    controller: function($scope) {
        $scope.removeElement = function(){
            //this where I want to access the parent function
            console.log($scope.$parent.getElementsList());
            console.log("ALSO I WANT TO ACCESS THIS DIRECTIVE elementId WITHOUT USING $scope", $scope.elementId);
        }
    }
  };
});

ParentController:

angular.module('myApp').controller('AppDesignCtrl', function ($scope) {
    var self = this;
    self.elementsList = [];
    self.getElementsList = function(){
        return self.elementsList;
    }

});

我还想知道在指令控制器中访问传递给指令$ scope的数据的最佳方法是什么。

scope: {
    elementId: '=elementid'
},

更新

<div>
   <i class="fa fa-arrows element-drag"></i>
   <i class="fa fa-trash-o element-remove" ng-click="removeElement()"></i>
</div>

那么从指令控制器内的指令模板调用函数呢?我是否需要使用$ scope.removeElement()之类的东西来公开它们?如何使用this.removeElement()并能够从模板中访问它?

很抱歉这个问题很长。我正试图为我的新项目设置最佳实践,因为我已离开角度一年+。

提前致谢

2 个答案:

答案 0 :(得分:1)

(从下到上......)

要在不使用Angular&gt; = 1.2中的范围的情况下调用控制器中的函数,请使用controllerAs语法:

<div ng-controller="AppDesignCtrl as appDesignCtrl">
    ...
    <i class="fa fa-trash-o element-remove" ng-click="appDesignCtrl.removeElement()"></i>
</div>

并且removeElement()必须是控制器的方法:

angular.module('myApp').controller('AppDesignCtrl', function ($scope) {
    ...
    this.removeElement = function() {
        ...
    };
});

要在Angular&gt; = 1.3中从控制器访问范围数据,请使用新的bindToController: true配置(当与新的controllerAs语法结合使用时,此功能特别有用):

angular.module('myApp').directive('accountBalance', function() {
    return {
        ...
        scope: {
            elementId: '=elementid'
        },
        controller: function() {
            // now elementId is a member of the controller:
            console.log(this.elementId);
        }
    };
});

说完这些之后,你可以从指令中调用getElementsList的答案是:

angular.module('myApp').directive('accountBalance', function() {
    return {
        ...
        scope: {
            elementId: '=elementid',
            getElementList: '&'
        },
        controller: function() {
            ...
            // invoking the expression that was passed to us
            var theElements = this.getElementList();
        }
    };
});

正确的表达式应该传递为:

<div ng-controller="AppDesignCtrl as appDesignCtrl">
    <account-balance element-id="xxx"
        get-elements-list="appDesignCtrl.getElementsList()"></account-balance>
</div>

答案 1 :(得分:1)

通常不建议使用,因为指令是自包含的。如果您不打算重复使用该指令,这一点并不重要。明智地使用隔离范围可以解决这个问题。

angular.module('myApp').directive('accountBalance', function() {
  return {
    scope: {
        outerScope: '@'
        elementId: '='
    },
    transclude: true,
    restrict: 'E',
    templateUrl: '../views_directives/account-balance.html',

    controller: function($scope) {
        console.log("we can use anything from other controller", $scope.outerScope.elementsList)
        $scope.elementId = "and share data with any other scope";
    }
  };
});

控制器定义为ng-controller="AppDesignCtrl as appDesign",指令用法为

<account-balance element-id="sharedParentScopeVar" outer-scope="appDesign">

如果指令应该移动到其他控制器,那么就不会有任何问题。

我认为最好的做法&#39;可能是设置一个包含数据的服务,并由app controller和directive使用,因此指令控制器对数据项而不是DOM元素进行操作。

  

那么从内部的指令模板调用函数呢?   指令的控制者?我需要暴露它们吗?   类似于$ scope.removeElement()?

你肯定不会。如果需要使用外部功能,您就会做错事。如果它与DOM相关,则向相应元素发送消息以运行该函数。或者如果函数与数据相关,则将函数放入服务中。