codememo

Angular의 상위 컨트롤러에서 디렉티브의 메서드를 호출합니다.JS

tipmemo 2023. 3. 14. 21:40
반응형

Angular의 상위 컨트롤러에서 디렉티브의 메서드를 호출합니다.JS

Angular를 사용하고 있습니다.에일리어스 컨트롤러 패턴을 가진 JS.부모 컨트롤러에서 지시 메서드에 액세스할 수 없습니다(또는 방법을 알 수 없습니다).

컨트롤러 내부에 디렉티브메서드를 호출해야 하는 함수가 있는데 이 디렉티브메서드는 내부에서는 사용할 수 없습니다.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>'
  };
});

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>

여기 코드가 있는 코드펜이 있습니다.

격리된 제품을 사용하고 싶은 경우scope방향성 안에서 방향성 방법은 다음과 같은 각도 이벤트를 사용하여 호출될 수 있습니다.$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>

코드

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>'
  };
});

자스코프의 호출방식 대신 이벤트를 브로드캐스트해야 합니다.지시범위에 따라 이벤트를 청취해야 합니다.그러면 이벤트가 실행됩니다.changeText그 이벤트를 듣고 나서의 방법.

메모

서비스/공장을 이용하는 것이 더 나을 것입니다.

이게 도움이 되길 바라.감사해요.

$broadcast에 의존하거나 스코프의 분리를 삭제하지 않고 발신 디렉티브 방식을 실현할 수 있습니다.지금까지 여기에 게시된 유사한 접근 방식은 페이지에 지시문 인스턴스가 2개 이상 있으면 중단됩니다(모두 동일한 변경 사항이 반영됨).

이 코드펜은 그것을 하는 더 강력한 방법을 보여준다.

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;
          };
        }
      }
    };
  
});
<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>

브로드캐스트에 의존하지 않고 격리된 스코프를 사용할 수 있는 다른 솔루션이 있습니다.javascript 메서드는 변수처럼 사용할 수 있으므로 원하는 메서드를 디렉티브에 전달하기만 하면 됩니다.

따라서 html:

<my-dir text="ctrl.dirText" change-text="ctrl.changeText"></my-dir>

지시적으로

scope: {
   text: '=',
   changeText: '='
 }

여기 약간 변형된 코데펜이 있는데, 제가 무슨 생각을 하는지 보실 수 있습니다.

다음을 작성할 때 스코프를 격리합니다.

 scope: {
       text: '='
     },

다음은 약간 수정된 버전의 코드입니다. 이번에는 디렉티브 메서드를 호출할 수 있습니다.거의 다 없앴어요'scope'명령어를 지정하고 컨트롤러에서 $scope를 사용하고 Alias 패턴을 사용하도록 변경했습니다.

경고: 이것은 변경되는 변수에 대한 올바른 동작을 반영하지 못할 수 있지만 컨트롤러에서 디렉티브 메서드에 액세스하는 방법을 보여줌으로써 질문에 답합니다.이것은 보통 좋은 디자인 아이디어가 아닙니다.

http://codepen.io/anon/pen/azwJBm

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

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

  $scope.text = 'Controller text';

  $scope.dirText = 'Directive text';

  $scope.click = function(){
    $scope.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>'
  };
});


<div ng-app="myApp">
  <div ng-controller="MyCtrl">
    <h1>{{text}}</h1>
    <my-dir text="dirText"></my-dir>
    <button ng-click="click()">Change Directive Text</button>
  </div>
</div>

$broadcastcontrol오브젝트 솔루션에서는 값이나 어레이를 바인드하는 것을 추천합니다.control오브젝트는 원하는 결과를 얻기 위한 간단한 방법이지만, 제 테스트에서는 검출할 수 없고 오류가 발생하기 쉽습니다.

이 Codepen은 BernardV의 예를 작성하지만 매우 가시적인 컨트롤 바인딩으로 메시지 배열을 사용합니다.네가 원한다면, 너는 쉽게 할 수 있다.$watch지시문 내의 메시지 배열도 마찬가지입니다.핵심 아이디어는 다음과 같이 직접 사용하는 것입니다.

scope: { messages: "=", room: "@" },

컨트롤러('룸'이 여러 개 있는 경우)에서 다음을 수행합니다.

$scope.addMessages = function () {
  angular.forEach($scope.rooms, function(room, index) {
    room.messages.push("A new message! # " + (index+1);
  })
} 

독자적인 지시, 독자적인 메시지, 고도의 검출성.물론 지시문에서는 최신 메시지만 표시하거나 배열 대신 문자열을 바인딩할 수도 있습니다.적어도 이 솔루션은 우리에게 훨씬 더 효과적이었습니다.

언급URL : https://stackoverflow.com/questions/28116680/calling-directives-methods-from-parent-controller-in-angularjs

반응형