从AngularJS中的父控制器调用指令的方法

ian*_*a89 26 javascript events angularjs angularjs-directive angularjs-controller

我正在使用带有别名控制器模式的AngularJS.我无法从父控制器访问(或者我不知道如何)指令方法.

我的控制器中有一个函数应该调用一个指令方法,但这个指令方法在this控制器值内不可用.

这就是我所拥有的.我做错了什么?

JS

angular.module('myApp', []).

controller('MyCtrl', function(){
  this.text = 'Controller text';

  this.dirText = 'Directive text';

  this.click = function(){
    this.changeText();
  }
})

.directive('myDir', function(){
  return {
     restrict: 'E',
     scope: {
       text: '='
     },
     link: function(scope, element, attrs){
       scope.changeText = function(){
         scope.text = 'New directive text';
       };
     },
     template: '<h2>{{text}}</h2>'
  };
});
Run Code Online (Sandbox Code Playgroud)

HTML

<div ng-app="myApp">
  <div ng-controller="MyCtrl as ctrl">
    <h1>{{ctrl.text}}</h1>
    <my-dir text="ctrl.dirText"></my-dir>
    <button ng-click="ctrl.click()">Change Directive Text</button>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

这里有代码的codepen.

Pan*_*kar 29

如果你只想scope在一个指令中使用isolated,那么只能通过使用诸如$broadcast&之类的角度事件来调用指令方法.$emit

在您的情况下,您需要使用$broadcast发送事件到整个$rootScope

您的代码将变为这样.

工作密码笔

HTML

<div ng-app="myApp">
  <div ng-controller="MyCtrl as ctrl">
    <h1>{{ctrl.text}}</h1>
    <my-dir text="ctrl.dirText"></my-dir>
    <button ng-click="ctrl.click()">Change Directive Text</button>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

angular.module('myApp', []).

controller('MyCtrl', function($rootScope){
  var that = this;

  this.text = 'Controller text';

  this.dirText = 'Directive text';

  this.click = function(){
      $rootScope.$broadcast('changeText',{});
  }
}).

directive('myDir', function(){
  return {
     restrict: 'E',
     scope: {
       text: '='
     },
     link: function(scope, element, attrs){
       scope.changeText = function(){
         scope.text = 'New directive text';
       };
         scope.$on('changeText',function(event, data){
             scope.changeText()
         });
     },
     template: '<h2>{{text}}</h2>'
  };
});
Run Code Online (Sandbox Code Playgroud)

您需要广播一个事件,而不是调用子范围的方法,该事件必须由指令范围changeText监听,并且在收听该事件后将触发方法.

注意

使用服务/工厂将是更好的方法.

这有望帮助你.谢谢.

  • @PankajParkar如果有人用户名'downvoter`他可能收到通知:D (6认同)
  • @ ianaya89谢谢.:)很高兴为您服务.但方法并不是那么好.. (3认同)

Ber*_*rdV 16

您可以实现调用指令方法,而无需依赖$ broadcast或删除范围隔离.如果页面上有2个以上的指令实例,那么到目前为止已经发布的类似方法将会中断(它们都会反映相同的更改).

这个codepen演示了一种更强大的方法.

angular.module('myApp', [])
.controller('myChat', function($scope) {
    
    function room () {return { accessor:{} }; }
    $scope.rooms = { 'RoomA': new room, 'RoomB': new room, 'RoomC': new room };

    $scope.addMessageTo = function(roomId, msg) {
      if ($scope.rooms[roomId].accessor.setMessage)
        $scope.rooms[roomId].accessor.setMessage(msg);
    };

    $scope.addMessages = function () {
      $scope.addMessageTo("RoomA", "A message");
      $scope.addMessageTo("RoomB", "Two messages");
      $scope.addMessageTo("RoomC", "More messages");
    }
    
}).directive('myChatRoom', function() {

    return {
      template: '<div>{{room}} message = {{message}}<div />',
      scope: { accessor: "=", room: "@" },
      link: function (scope) {
        if (scope.accessor) {
          scope.accessor.setMessage = function(msg) {
            scope.message = msg;
          };
        }
      }
    };
  
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="myChat">

    <div ng-repeat="(roomId, room) in rooms">
      <div my-chat-room room="{{roomId}}" accessor="room.accessor"></div>
    </div>

    <button ng-click="addMessages()">Add messages to rooms</button>

  </div>
</div>
Run Code Online (Sandbox Code Playgroud)


小智 11

我有另一种解决方案,它允许你使用隔离范围而不依赖于广播.在javascript方法中可以像变量一样使用,你可以简单地将你想要的方法传递给指令.

所以在HTML中:

<my-dir text="ctrl.dirText" change-text="ctrl.changeText"></my-dir>
Run Code Online (Sandbox Code Playgroud)

并在指令中

scope: {
   text: '=',
   changeText: '='
 }
Run Code Online (Sandbox Code Playgroud)

是一个稍微修改过的codepen,在那里你可以看到我的想法.

  • 你正在将**父亲的**方法传递给指令,但问题是反方向 (3认同)