angularjs - parametros - ng click angular 6
¿Cómo exponer una API pública de una directiva que es un componente reutilizable? (5)
¿Esto funciona para tí?
angular.directive(''extLabel'', function() {
return {
restrict: ''E'',
scope: {
api: ''=''
},
link: function(scope, iElement, iAttrs) {
scope.api = {
doSomething: function() { },
doMore: function() { }
};
}
};
});
De contener padre
<ext:label api="myCoolApi"></ext:label>
Y en el controlador
$scope.myCoolApi.doSomething();
$scope.myCoolApi.doMore();
Teniendo una directiva en angular que es un componente reutilizable, ¿cuál es la mejor práctica para exponer una API pública a la que se puede acceder desde el controlador? Entonces, cuando hay múltiples instancias del componente, puede tener acceso desde el controlador
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;
}
}
}
});
Entonces cuando tienes:
<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>
¿Cómo puedo obtener acceso al scope.changeLabel de extLabel2 en un controlador?
¿Tiene sentido?
En mi opinión, un padre no debería tener acceso al alcance de los niños. ¿Cómo sabría cuál usar y cuál no usar? Un controlador debe acceder a su propio alcance o solo a sus ámbitos principales. Se rompe la encapsulación de lo contrario.
Si desea cambiar su etiqueta, todo lo que necesita hacer es cambiar el valor de la variable label1 / label2 / label3. Con el enlace de datos habilitado, debería funcionar. Dentro de su directiva, puede $watch
si necesita algo de lógica cada vez que cambia.
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
});
}
}
});
Me enfrenté a este problema al escribir una directiva para crear una instancia de un gráfico de diagramas en mis aplicaciones angulares. Aunque la mayor parte del trabajo puede realizarse mediante el enlace de datos, algunas partes de la API requieren acceso al propio objeto de gráfico. Lo resolví por $emit()
ing un evento:
''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);
}
};
});
Los parámetros del evento dygraphCreated
incluyen el identificador de elemento así como el objeto dygraph, lo que permite utilizar varios dygraphs dentro del mismo ámbito.
Me gusta Andrej''s y uso este patrón regularmente, pero me gustaría sugerirle algunos cambios.
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>
En el controlador del curso label2api.changeLabel(''label'')
Utilice estas directivas sobre el elemento que desea ir al siguiente y al siguiente:
<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()]);
});
}
};
})