programing

다른 컨트롤러로부터의 디렉티브컨트롤러 호출방식

copysource 2023. 3. 26. 14:09
반응형

다른 컨트롤러로부터의 디렉티브컨트롤러 호출방식

나한테는 제어 장치가 있는 지시가 있어다음 코드를 참조하십시오.

var popdown = angular.module('xModules',[]);

popdown.directive('popdown', function () {
    var PopdownController = function ($scope) {
        this.scope = $scope;
    }

    PopdownController.prototype = {
        show:function (message, type) {
            this.scope.message = message;
            this.scope.type = type;
        },

        hide:function () {
            this.scope.message = '';
            this.scope.type = '';
        }
    }

    var linkFn = function (scope, lElement, attrs, controller) {

    };

    return {
        controller: PopdownController,
        link: linkFn,
        replace: true,
        templateUrl: './partials/modules/popdown.html'
    }

});

이는 오류/알림/경고 알림 시스템입니다.다른 컨트롤러(지시 컨트롤러가 아닌)에서 함수를 호출하고 싶다.show이 컨트롤러에 접속합니다.그 때, 링크 기능에 의해서, 몇개의 속성이 변경되고 있는 것을 검출해 애니메이션을 실행해 주었으면 합니다.

다음은 제가 요청하는 것의 예를 보여 주는 몇 가지 코드입니다.

var app = angular.module('app', ['RestService']);

app.controller('IndexController', function($scope, RestService) {
    var result = RestService.query();

    if(result.error) {
        popdown.notify(error.message, 'error');
    }
});

그래서 전화할 때show에서popdown지시 컨트롤러, 링크 기능도 트리거되고 애니메이션을 수행해야 합니다.제가 어떻게 그걸 할 수 있을까요?

이것은 흥미로운 질문입니다.그리고 저는 이런 것을 어떻게 구현해야 할지 고민하기 시작했습니다.

제가 이걸 생각해 냈어요.

기본적으로 컨트롤러에서 명령을 호출하는 대신 모든 팝업 로직을 저장하는 모듈을 만들었습니다.

var PopdownModule = angular.module('Popdown', []);

모듈에 두 가지를 넣었습니다.factory어디에나 삽입할 수 있는 API와directive실제 팝다운 요소의 동작을 정의합니다.

공장에서는 몇 가지 기능만 정의하고 있습니다.success그리고.error는 몇 가지 변수를 추적합니다.

PopdownModule.factory('PopdownAPI', function() {
    return {
        status: null,
        message: null,
        success: function(msg) {
            this.status = 'success';
            this.message = msg;
        },
        error: function(msg) {
            this.status = 'error';
            this.message = msg;
        },
        clear: function() {
            this.status = null;
            this.message = null;
        }
    }
});

디렉티브는 컨트롤러에 API를 삽입하여 API의 변경을 감시합니다(편의상 부트스트랩 css를 사용하고 있습니다).

PopdownModule.directive('popdown', function() {
    return {
        restrict: 'E',
        scope: {},
        replace: true,
        controller: function($scope, PopdownAPI) {
            $scope.show = false;
            $scope.api = PopdownAPI;

            $scope.$watch('api.status', toggledisplay)
            $scope.$watch('api.message', toggledisplay)

            $scope.hide = function() {
                $scope.show = false;
                $scope.api.clear();
            };

            function toggledisplay() {
                $scope.show = !!($scope.api.status && $scope.api.message);               
            }
        },
        template: '<div class="alert alert-{{api.status}}" ng-show="show">' +
                  '  <button type="button" class="close" ng-click="hide()">&times;</button>' +
                  '  {{api.message}}' +
                  '</div>'
    }
})

그럼 내가 정의해줄게app의존하는 모듈Popdown:

var app = angular.module('app', ['Popdown']);

app.controller('main', function($scope, PopdownAPI) {
    $scope.success = function(msg) { PopdownAPI.success(msg); }
    $scope.error   = function(msg) { PopdownAPI.error(msg); }
});

HTML은 다음과 같습니다.

<html ng-app="app">
    <body ng-controller="main">
        <popdown></popdown>
        <a class="btn" ng-click="success('I am a success!')">Succeed</a>
        <a class="btn" ng-click="error('Alas, I am a failure!')">Fail</a>
    </body>
</html>

이것이 완전히 이상적인지는 모르겠지만, 글로벌한 팝다운 디렉티브로 커뮤니케이션을 확립하는 합리적인 방법인 것 같습니다.

다시 한 번 말씀드리지만, 바이올린입니다.

이벤트를 사용하여 팝다운을 트리거할 수도 있습니다.

여기 새치모런의 솔루션에 기초한 바이올린이 있습니다.팝다운으로 처리됩니다.API와 대신 최상위 컨트롤러가 있습니다.$broadcasts s success 이벤트와 error 이벤트가 스코프 체인 아래로 이동합니다.

$scope.success = function(msg) { $scope.$broadcast('success', msg); };
$scope.error   = function(msg) { $scope.$broadcast('error', msg); };

그런 다음 팝업 모듈은 다음과 같은 이벤트에 대한 핸들러 기능을 등록합니다.

$scope.$on('success', function(event, msg) {
    $scope.status = 'success';
    $scope.message = msg;
    $scope.toggleDisplay();
});

적어도 이것은 효과가 있고, 나에게는 잘 분리된 해결책으로 보인다.만약 이것이 어떤 이유로 나쁜 연습으로 여겨진다면, 나는 다른 사람들이 끼어들게 할 것이다.

디렉티브의 컨트롤러를 부모 스코프에 노출시킬 수도 있습니다.ngForm와 함께nameattribute does:http://docs.angularjs.org/api/ng.directive:ngForm

이 예에서는, http://plnkr.co/edit/Ps8OXrfpnePFvvdFgYJf?p=preview 를 참조할 수 있습니다.

에서는, 「」가 .myDirective와 '''가 있는 경우$clearmethod(API).이 컨트롤러를 부모 스코프에 퍼블리시하여 디렉티브 밖에서 이 메서드를 사용할 수 있습니다.

나는 훨씬 더 나은 해결책을 얻었다.

이것은 나의 지시문입니다, 나는 지시문 내의 객체 참조에 주입했고 지시문 코드에 호출 함수를 추가함으로써 그것을 확장했습니다.

app.directive('myDirective', function () {
    return {
        restrict: 'E',
        scope: {
        /*The object that passed from the cntroller*/
        objectToInject: '=',
다른 컨트롤러로부터의 디렉티브컨트롤러 호출방식        },
        templateUrl: 'templates/myTemplate.html',

        link: function ($scope, element, attrs) {
            /*This method will be called whet the 'objectToInject' value is changes*/
            $scope.$watch('objectToInject', function (value) {
                /*Checking if the given value is not undefined*/
                if(value){
                $scope.Obj = value;
                    /*Injecting the Method*/
                    $scope.Obj.invoke = function(){
                        //Do something
                    }
                }    
            });
        }
    };
});

매개 변수를 사용하여 HTML에 지시문 선언:

<my-directive object-to-inject="injectedObject"></ my-directive>

컨트롤러:

app.controller("myController", ['$scope', function ($scope) {
   // object must be empty initialize,so it can be appended
    $scope.injectedObject = {};

    // now i can directly calling invoke function from here 
     $scope.injectedObject.invoke();
}];

언급URL : https://stackoverflow.com/questions/14883476/call-method-in-directive-controller-from-other-controller

반응형