AngularJS
Servicios
Buscar..
Cómo crear un servicio
angular.module("app")
.service("counterService", function(){
var service = {
number: 0
};
return service;
});
Cómo utilizar un servicio
angular.module("app")
// Custom services are injected just like Angular's built-in services
.controller("step1Controller", ['counterService', '$scope', function(counterService, $scope) {
counterService.number++;
// bind to object (by reference), not to value, for automatic sync
$scope.counter = counterService;
})
En la plantilla que usa este controlador, escribirías:
// editable
<input ng-model="counter.number" />
o
// read-only
<span ng-bind="counter.number"></span>
Por supuesto, en código real, interactuarías con el servicio utilizando métodos en el controlador, que a su vez delegan en el servicio. El ejemplo anterior simplemente incrementa el valor del contador cada vez que se usa el controlador en una plantilla.
Servicios en Angularjs son singletons:
Los servicios son objetos singleton que se instancian solo una vez por aplicación (por el $ inyector) y se cargan perezosamente (creados solo cuando es necesario).
Un singleton es una clase que solo permite crear una instancia de sí mismo, y brinda un acceso simple y fácil a dicha instancia. Como se indica aquí
Creando un servicio usando angular.factory
Primero defina el servicio (en este caso usa el patrón de fábrica):
.factory('dataService', function() {
var dataObject = {};
var service = {
// define the getter method
get data() {
return dataObject;
},
// define the setter method
set data(value) {
dataObject = value || {};
}
};
// return the "service" object to expose the getter/setter
return service;
})
Ahora puedes usar el servicio para compartir datos entre controladores:
.controller('controllerOne', function(dataService) {
// create a local reference to the dataService
this.dataService = dataService;
// create an object to store
var someObject = {
name: 'SomeObject',
value: 1
};
// store the object
this.dataService.data = someObject;
})
.controller('controllerTwo', function(dataService) {
// create a local reference to the dataService
this.dataService = dataService;
// this will automatically update with any changes to the shared data object
this.objectFromControllerOne = this.dataService.data;
})
$ sce - desinfecta y representa contenido y recursos en plantillas
$ sce ("Escape Contextual Estricto") es un servicio angular incorporado que automáticamente desinfecta el contenido y las fuentes internas en las plantillas.
inyectar fuentes externas y HTML en bruto en la plantilla requiere el ajuste manual de $sce
.
En este ejemplo crearemos un filtro de saneamiento simple $ sce: `.
.filter('sanitizer', ['$sce', [function($sce) {
return function(content) {
return $sce.trustAsResourceUrl(content);
};
}]);
Uso en plantilla
<div ng-repeat="item in items">
// Sanitize external sources
<ifrmae ng-src="{{item.youtube_url | sanitizer}}">
// Sanitaize and render HTML
<div ng-bind-html="{{item.raw_html_content| sanitizer}}"></div>
</div>
Cómo crear un servicio con dependencias usando 'sintaxis de matriz'
angular.module("app")
.service("counterService", ["fooService", "barService", function(anotherService, barService){
var service = {
number: 0,
foo: function () {
return fooService.bazMethod(); // Use of 'fooService'
},
bar: function () {
return barService.bazMethod(); // Use of 'barService'
}
};
return service;
}]);
Registro de un servicio
La forma más común y flexible de crear un servicio utiliza la fábrica de API angular.module:
angular.module('myApp.services', []).factory('githubService', function() {
var serviceInstance = {};
// Our first service
return serviceInstance;
});
La función de fábrica de servicios puede ser una función o una matriz, al igual que la forma en que creamos los controladores:
// Creating the factory through using the
// bracket notation
angular.module('myApp.services', [])
.factory('githubService', [function($http) {
}]);
Para exponer un método en nuestro servicio, podemos colocarlo como un atributo en el objeto de servicio.
angular.module('myApp.services', [])
.factory('githubService', function($http) {
var githubUrl = 'https://api.github.com';
var runUserRequest = function(username, path) {
// Return the promise from the $http service
// that calls the Github API using JSONP
return $http({
method: 'JSONP',
url: githubUrl + '/users/' +
username + '/' +
path + '?callback=JSON_CALLBACK'
});
}
// Return the service object with a single function
// events
return {
events: function(username) {
return runUserRequest(username, 'events');
}
};
Diferencia entre Servicio y Fábrica.
1) Servicios
Un servicio es una función de constructor
que se invoca una vez en tiempo de ejecución con el new
, al igual que lo que haríamos con el Javascript simple con la única diferencia de que AngularJs
está llamando al new
detrás de escena.
Hay una regla del pulgar para recordar en caso de servicios
- Los servicios son constructores que se llaman con
new
Veamos un ejemplo sencillo en el que registraríamos un servicio que usa el servicio $http
para obtener los detalles de los estudiantes y usarlos en el controlador
function StudentDetailsService($http) {
this.getStudentDetails = function getStudentDetails() {
return $http.get('/details');
};
}
angular.module('myapp').service('StudentDetailsService', StudentDetailsService);
Acabamos de inyectar este servicio en el controlador.
function StudentController(StudentDetailsService) {
StudentDetailsService.getStudentDetails().then(function (response) {
// handle response
});
}
angular.module('app').controller('StudentController', StudentController);
¿Cuándo usar?
Use .service()
donde quiera que quiera usar un constructor. Normalmente se usa para crear API públicas como getStudentDetails()
. Pero si no desea usar un constructor y desea usar un patrón de API simple, entonces no hay mucha flexibilidad en .service()
.
2) Fábrica
A pesar de que podemos lograr todas las cosas usando .factory()
que haríamos, usando .services()
, no hace que .factory()
"igual que" .service()
. Es mucho más potente y flexible que .service()
Un .factory()
es un patrón de diseño que se utiliza para devolver un valor.
Hay dos reglas para recordar en caso de fábricas.
- Fábricas devuelven valores
- Fábricas (pueden) crear objetos (cualquier objeto)
Veamos algunos ejemplos de lo que podemos hacer usando .factory()
Devolviendo objetos literales
Veamos un ejemplo donde se usa la fábrica para devolver un objeto usando un patrón de módulo Revelación básico
function StudentDetailsService($http) {
function getStudentDetails() {
return $http.get('/details');
}
return {
getStudentDetails: getStudentDetails
};
}
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
Uso dentro de un controlador
function StudentController(StudentDetailsService) {
StudentDetailsService.getStudentDetails().then(function (response) {
// handle response
});
}
angular.module('app').controller('StudentController', StudentController);
Cierres de retorno
¿Qué es un cierre?
Los cierres son funciones que se refieren a variables que se usan localmente, PERO definidas en un ámbito de cierre.
A continuación se muestra un ejemplo de un cierre.
function closureFunction(name) {
function innerClosureFunction(age) { // innerClosureFunction() is the inner function, a closure
// Here you can manipulate 'age' AND 'name' variables both
};
};
La parte "maravillosa" es que puede acceder al name
que está en el ámbito principal.
Vamos a usar el ejemplo de cierre anterior en .factory()
function StudentDetailsService($http) {
function closureFunction(name) {
function innerClosureFunction(age) {
// Here you can manipulate 'age' AND 'name' variables
};
};
};
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
Uso dentro de un controlador
function StudentController(StudentDetailsService) {
var myClosure = StudentDetailsService('Student Name'); // This now HAS the innerClosureFunction()
var callMyClosure = myClosure(24); // This calls the innerClosureFunction()
};
angular.module('app').controller('StudentController', StudentController);
Creación de constructores / instancias
.service()
crea constructores con una llamada a new
como se ve arriba. .factory()
también puede crear constructores con una llamada a new
Veamos un ejemplo de cómo lograr esto.
function StudentDetailsService($http) {
function Student() {
this.age = function () {
return 'This is my age';
};
}
Student.prototype.address = function () {
return 'This is my address';
};
return Student;
};
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
Uso dentro de un controlador
function StudentController(StudentDetailsService) {
var newStudent = new StudentDetailsService();
//Now the instance has been created. Its properties can be accessed.
newStudent.age();
newStudent.address();
};
angular.module('app').controller('StudentController', StudentController);