다른 컨트롤러에서 지시어 컨트롤러의 메소드 호출
자체 컨트롤러가있는 지시문이 있습니다. 아래 코드를 참조하십시오 :
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실제 popdown 요소의 동작을 정의하기위한 것입니다.
공장은 기능의 몇 가지를 정의 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>
그것이 이상적인지 확실하지는 않지만, 글로벌 팝 다운 지시문과의 통신을 설정하는 합리적인 방법처럼 보입니다.
Again, for reference, the fiddle.
You can also use events to trigger the Popdown.
Here's a fiddle based on satchmorun's solution. It dispenses with the PopdownAPI, and the top-level controller instead $broadcasts 'success' and 'error' events down the scope chain:
$scope.success = function(msg) { $scope.$broadcast('success', msg); };
$scope.error = function(msg) { $scope.$broadcast('error', msg); };
The Popdown module then registers handler functions for these events, e.g:
$scope.$on('success', function(event, msg) {
$scope.status = 'success';
$scope.message = msg;
$scope.toggleDisplay();
});
This works, at least, and seems to me to be a nicely decoupled solution. I'll let others chime in if this is considered poor practice for some reason.
You could also expose the directive's controller to the parent scope, like ngForm with name attribute does: http://docs.angularjs.org/api/ng.directive:ngForm
Here you could find a very basic example how it could be achieved http://plnkr.co/edit/Ps8OXrfpnePFvvdFgYJf?p=preview
In this example I have myDirective with dedicated controller with $clear method (sort of very simple public API for the directive). I can publish this controller to the parent scope and use call this method outside the directive.
I got much better solution .
here is my directive , I have injected on object reference in directive and has extend that by adding invoke function in directive code .
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
}
}
});
}
};
});
Declaring the directive in the HTML with a parameter:
<my-directive object-to-inject="injectedObject"></ my-directive>
my Controller:
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();
}];
'Programing' 카테고리의 다른 글
| Java8 : java.lang.Object에서 메소드의 기본 메소드를 정의하는 것이 금지 된 이유 (0) | 2020.07.17 |
|---|---|
| 기능적 언어에서 '패턴 일치'란 무엇입니까? (0) | 2020.07.17 |
| 어떤 i 값이 while (i == i + 1) {}을 영원히 반복합니까? (0) | 2020.07.17 |
| std :: optional을 어떻게 사용해야합니까? (0) | 2020.07.17 |
| Factory Girl에서 has_and_belongs_to_many 연관을 작성하는 방법 (0) | 2020.07.17 |