Decorador AngularJS sin object.defineProperty
-
24-12-2019 - |
Pregunta
¿Cómo uso decoradores sin tener acceso a object.defineProperty?
Estoy mirando las calzas disponibles:
pero en caso de que no pasen las pruebas, ¿hay otra forma en la que deberían funcionar los decoradores?
Estoy usando el decorador para $onRootScope.
Estoy usando angular 1.08.Necesito compatibilidad con IE7.
Actualizar
He probado algunos métodos que parecen funcionar pero no sé la diferencia entre ellos: plunkr
var app = angular.module('plunker', []);
app.config(['$provide', function($provide){
$provide.decorator('$rootScope', ['$delegate', function($delegate){
$delegate.a = 1;
$delegate.constructor.prototype.b = 2;
Object.defineProperty($delegate.constructor.prototype, 'c', {
value: 3
});
return $delegate;
}]);
}]);
app.controller('MainCtrl', function($rootScope, $scope) {
console.log($rootScope); //reveals `a` property
console.log($rootScope.constructor.prototype); //=> {b:2, c:3}
console.log($rootScope.a); //=> 1
console.log($rootScope.b); //=> 2
console.log($rootScope.c); //=> 3
$scope.name = 'World';
});
Gracias.
Solución
Bueno, una solución equivalente al fragmento de código que compartiste es:
var proto = Object.getPrototypeOf(Object.getPrototypeOf($delegate));
proto['$onRootScope'] = function (name, listener) {
var unsubscribe = $delegate.$on(name, listener);
this.$on('$destroy', unsubscribe);
};
En el código original esta línea $delegate.constructor.prototype
está obteniendo acceso al prototipo del $delegate.
Luego, una vez que tengas acceso a él, simplemente puedes definir una nueva función en él.No necesitas usar defineProperty
.La única advertencia es que al usar defineProperty
puede configurar que el método no sea enumerable (no debería aparecer en los bucles for-each).De esta otra forma, el método agregado aparecería en bucles for-each.Aunque puede que no sea un problema para ti.
he creado un JSFiddle para esto.
Puedes usar Polyfill de John Resig para getObjectPrototypeOf
si la función no está disponible para su navegador actual:
if ( typeof Object.getPrototypeOf !== "function" ) { if ( typeof "test".__proto__ === "object" ) { Object.getPrototypeOf = function(object){ return object.__proto__; }; } else { Object.getPrototypeOf = function(object){ // May break if the constructor has been tampered with return object.constructor.prototype; }; } }