재사용 가능한 컴포넌트인 디렉티브에서 퍼블릭 API를 공개하려면 어떻게 해야 합니까?
재사용 가능한 컴포넌트인 angular 명령어가 있는 경우 컨트롤러에서 액세스할 수 있는 퍼블릭 API를 공개하기 위한 베스트 프랙티스는 무엇입니까?따라서 컴포넌트의 인스턴스가 여러 개 있는 경우 컨트롤러에서 액세스할 수 있습니다.
angular.directive('extLabel', function {
return {
scope: {
name: '@',
configObj: '='
},
link: function(scope, iElement, iAttrs) {
// this could be and exposed method
scope.changeLabel = function(newLabel) {
scope.configObj.label = newLabel;
}
}
}
});
다음에 해당하는 경우:
<ext-label name="extlabel1" config-obj="label1"></ext-label>
<ext-label name="extlabel2" config-obj="label2"></ext-label>
<ext-label name="extlabel3" config-obj="label3"></ext-label>
컨트롤러에서 extLabel2의 scope.changeLabel에 액세스하려면 어떻게 해야 하나요?
그게 말이 되는 건가요?
이거 괜찮으세요?
angular.directive('extLabel', function() {
return {
restrict: 'E',
scope: {
api: '='
},
link: function(scope, iElement, iAttrs) {
scope.api = {
doSomething: function() { },
doMore: function() { }
};
}
};
});
부모 포함에서
<ext:label api="myCoolApi"></ext:label>
컨트롤러 내
$scope.myCoolApi.doSomething();
$scope.myCoolApi.doMore();
저는 Andrej를 좋아하고 이 패턴을 자주 사용하지만, 몇 가지 변경을 제안하고 싶습니다.
angular.directive('extLabel', function {
return {
scope: {
api: '=?',
configObj: '='
},
// A controller, and not a link function. From my understanding,
// try to use the link function for things that require post link actions
// (for example DOM manipulation on the directive)
controller: ['$scope', function($scope) {
// Assign the api just once
$scope.api = {
changeLabel: changeLabel
};
function changeLabel = function(newLabel) {
$scope.configObj.label = newLabel;
}
}]
}
});
<ext-label name="extlabel1" config-obj="label1"></ext-label>
<ext-label api="label2api" name="extlabel2" config-obj="label2"></ext-label>
<ext-label name="extlabel3" config-obj="label3"></ext-label>
물론 컨트롤러 내label2api.changeLabel('label')
Angular 어플리케이션에서 Dygraph 차트를 인스턴스화하는 명령을 작성할 때 이 문제에 직면했습니다.대부분의 작업은 데이터 바인딩을 통해 수행될 수 있지만 API의 일부 부분에서는 dygraph 객체 자체에 대한 액세스가 필요합니다.나는 그것을 해결했다$emit()
이벤트 입력:
'use strict';
angular.module('dygraphs', []);
angular.module('dygraphs').directive('mrhDygraph', function ($parse, $q) {
return {
restrict: 'A',
replace: true,
scope: {data: '=', initialOptions: '@', options: '='},
link: function (scope, element, attrs) {
var dataArrived = $q.defer();
dataArrived.promise.then(function (graphData) {
scope.graph = new Dygraph(element[0], graphData, $parse(scope.initialOptions)(scope.$parent));
return graphData.length - 1;
}).then(function(lastPoint) {
scope.graph.setSelection(lastPoint);
scope.$emit('dygraphCreated', element[0].id, scope.graph);
});
var removeInitialDataWatch = scope.$watch('data', function (newValue, oldValue, scope) {
if ((newValue !== oldValue) && (newValue.length > 0)) {
dataArrived.resolve(newValue);
removeInitialDataWatch();
scope.$watch('data', function (newValue, oldValue, scope) {
if ((newValue !== oldValue) && (newValue.length > 0)) {
var selection = scope.graph.getSelection();
if (selection > 0) {
scope.graph.clearSelection(selection);
}
scope.graph.updateOptions({'file': newValue});
if ((selection >= 0) && (selection < newValue.length)) {
scope.graph.setSelection(selection);
}
}
}, true);
scope.$watch('options', function (newValue, oldValue, scope) {
if (newValue !== undefined) {
scope.graph.updateOptions(newValue);
}
}, true);
}
}, true);
}
};
});
의 파라미터dygraphCreated
이벤트에는 요소 ID와 Dygraph 객체가 포함되어 여러 개의 Dygraph를 동일한 범위 내에서 사용할 수 있습니다.
제 생각에는 부모가 자녀의 범위에 접근해서는 안 됩니다.어떤 것을 사용할지, 어떤 것을 사용하지 않을지 어떻게 알 수 있습니까?컨트롤러는 자신의 범위 또는 부모 범위에만 액세스해야 합니다.그렇지 않으면 캡슐화가 해제됩니다.
라벨을 변경하려면 label1/label2/label3 변수 값만 변경하면 됩니다.데이터 바인딩을 유효하게 하면, 동작합니다.지시사항 내에서는$watch
바뀔 때마다 논리적인 것이 필요하시면요.
angular.directive('extLabel', function {
return {
scope: {
name: '@',
configObj: '='
},
link: function(scope, iElement, iAttrs) {
scope.$watch("configObj", function() {
// Do whatever you need to do when it changes
});
}
}
});
다음 지시문은 이전 및 다음으로 이동하는 요소에서 사용합니다.
<carousel>
<slide>
<button class="action" carousel-next> Next </button>
<button class="action" carousel-prev> Back </button>
</slide>
</carousel>
.directive('carouselNext', function () {
return {
restrict: 'A',
scope: {},
require: ['^carousel'],
link: function (scope, element, attrs, controllers) {
var carousel = controllers[0];
function howIsNext() {
if ((carousel.indexOfSlide(carousel.currentSlide) + 1) === carousel.slides.length) {
return 0;
} else {
return carousel.indexOfSlide(carousel.currentSlide) + 1;
}
}
element.bind('click', function () {
carousel.select(carousel.slides[howIsNext()]);
});
}
};
})
.directive('carouselPrev', function () {
return {
restrict: 'A',
scope: {},
require: ['^carousel'],
link: function (scope, element, attrs, controllers) {
var carousel = controllers[0];
function howIsPrev() {
if (carousel.indexOfSlide(carousel.currentSlide) === 0) {
return carousel.slides.length;
} else {
return carousel.indexOfSlide(carousel.currentSlide) - 1;
}
}
element.bind('click', function () {
carousel.select(carousel.slides[howIsPrev()]);
});
}
};
})
언급URL : https://stackoverflow.com/questions/18533370/how-to-expose-a-public-api-from-a-directive-that-is-a-reusable-component
'programing' 카테고리의 다른 글
JSON 키 이름 가져오기 (0) | 2023.03.06 |
---|---|
하위 등급의 반응 코드에 대한 구문 강조 표시 (0) | 2023.03.06 |
TypeScript의 개체 리터럴에 정의를 입력합니다. (0) | 2023.03.06 |
React에서 JSON 파일 가져오기 (0) | 2023.03.06 |
Gson 옵션 및 필수 필드 (0) | 2023.03.06 |