자체 컨트롤러가있는 지시문이 있습니다. 아래 코드를 참조하십시오.
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()">×</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>
완전히 이상적인 것인지는 모르겠지만, 글로벌 팝 다운 지시문으로 통신을 설정하는 합리적인 방법 인 것 같았습니다.
다시 참고로 바이올린 .
답변
이벤트를 사용하여 Popdown을 트리거 할 수도 있습니다.
다음 은 satchmorun의 솔루션을 기반으로 한 바이올린 입니다. PopdownAPI를 생략하고 최상위 컨트롤러는 대신 $broadcast
범위 체인 아래에서 ‘성공’및 ‘오류’이벤트를 처리합니다.
$scope.success = function(msg) { $scope.$broadcast('success', msg); };
$scope.error = function(msg) { $scope.$broadcast('error', msg); };
그런 다음 Popdown 모듈은 이러한 이벤트에 대한 핸들러 함수를 등록합니다. 예 :
$scope.$on('success', function(event, msg) {
$scope.status = 'success';
$scope.message = msg;
$scope.toggleDisplay();
});
이것은 적어도 작동하며 나에게 멋지게 분리 된 솔루션 인 것 같습니다. 어떤 이유로 든 이것이 좋지 않다고 생각되면 다른 사람들에게 차임 할 것입니다.
답변
당신은 또한 같은 부모 범위에 지시어의 컨트롤러를 노출 수 ngForm
와 name
특성을 수행합니다 http://docs.angularjs.org/api/ng.directive:ngForm
여기에서 어떻게 달성 할 수 있는지 매우 기본적인 예를 찾을 수 있습니다. http://plnkr.co/edit/Ps8OXrfpnePFvvdFgYJf?p=preview
이 예제에서는 메서드 가 myDirective
있는 전용 컨트롤러 $clear
(지시문에 대한 매우 간단한 공용 API)가 있습니다. 이 컨트롤러를 부모 범위에 게시하고 지시문 외부에서이 메서드를 호출 할 수 있습니다.
답변
나는 훨씬 더 나은 해결책을 얻었다.
여기에 내 지시문이 있습니다. 지시문의 개체 참조에 삽입하고 지시문 코드에 invoke 함수를 추가하여 확장했습니다.
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();
}];