templateurl link directivas angularjs angularjs-directive angularjs-scope rootscope

link - directivas angularjs



Angularjs-$ rootScope en la funciĆ³n de enlace de directivas (6)

Estoy haciendo esta pregunta porque no tengo muy claro cómo pensar en el rootscope como una dependencia que pasa a las directivas

Tengo una directiva que necesita mostrar cierta información de $ rootScope ...

Pensé que necesitaba pasar el $ rootScope a una directiva, pero cuando escribo una directiva como esta parece funcionar.

.directive("myBar", function () { return { restrict: "E", transclude: true, replace: true, template: ''<div>'' + ''<span ng-transclude></span>'' + ''{{rsLabels.welcome}} {{rsUser.firstName}}!'' + ''</div>'' } })

¿Cuándo debo hacer esto?

.directive("myBar", function ($rootScope) { return { restrict: "E", transclude: true, replace: true, template: ''<div>'' + ''<span ng-transclude></span>'' + ''{{rsLabels.welcome}} {{rsUser.firstName}}!'' + ''</div>'' } })

¿Puedo y CÓMO uso rootScope si lo necesito en la función de enlace de la directiva , o debería hacerlo en el controlador de la directiva?

.directive("myBar", function ($rootScope) { return { restrict: "E", transclude: true, replace: true, link: function (scope, element, attrs, rootScope) { rootScope.rsUser = { firstName: ''Joe'' }; rootScope.rsUser = { welcome: ''Welcome'' }; }, template: ''<div>'' + ''<span ng-transclude></span>'' + ''{{rsLabels.welcome}} {{rsUser.firstName}}!'' + ''</div>'' } })

Mis datos de rootScope están definidos en la función de ejecución

.run(function ($rootScope) { $rootScope.rsLabels = { welcome: ''Welcome'' }; $rootScope.rsUser = { firstName: ''Joe'' }; });

¡Gracias!


A veces tengo que usar $ scope. $ Root:

app.directive(''setOrdinal'', function() { return { link: function($scope, $element, $attr) { var steps = $scope.$root.steps; $scope.$watch(setOrdinal, function(value) { if (value) { // steps code here } }); } }; }); app.controller(''stepController'', [''$scope'', ''$rootScope'', ''GetSteps'', function ($scope, $rootScope, GetSteps) { var s = $scope; var r = $rootScope; s.initialize = function(id) { GetSteps.get({id: id}, function(resp){ r.steps = resp.steps; }); }; }]);


Desde mis experimentos / experiencia, parece que como todos los $ scopes finalmente heredan de $ rootScope, podrá acceder a los datos en él sin solicitarlo como un servicio, siguiendo las reglas estándar de herencia prototípica de JavaScript. Si fueras a establecer la propiedad de alcance en tu directiva en falso o {}, encontrarás que ya no puedes acceder a ella.

.directive("myBar", function($rootScope) { return { restrict: "E", scope: { /* Isolate scope, no $rootScope access anymore */ }, transclude: true, replace: true, template: ''<div>'' + ''<span ng-transclude></span>'' + ''{{rsLabels.welcome}} {{rsUser.firstName}}!'' + ''</div>'' }; });

Ejemplo: http://jsbin.com/bequy/1/edit


Después de trabajar mucho en esta misma cuestión durante bastante tiempo, pensé que valía la pena señalar algo que se descuidó en la primera publicación. Aquí está mi código original:

app.directive(''countrymap'', function() { return { link: function(scope, element, attrs) { scope.$watch("countryMap", function (newCountry, oldCountry) { setTimeout( function() { //function body here }, 100); }) } }; }]);

Además de la cuestión del diseño más filosófico de si debería o no usar $ rootScope, hay una cosa descaradamente mal con mi código anterior que siento que se quedó fuera de la solución de Mike: la referencia a $ rootScope. Si eres como yo y has segregado tus archivos de directivas y controladores, deberás modificar tu código de la siguiente manera:

app.directive(''countrymap'', [''$rootScope'', function($rootScope) { return { link: function(scope, element, attrs) { $rootScope.$watch("countryMap", function (newCountry, oldCountry) { setTimeout( function() { //function body here }, 100); }) } }; }]);

Sin embargo, todavía hay una pregunta más persistente: ¿puedo lograr el mismo objetivo sin hacer referencia a $ rootScope en la directiva? De hecho, puedes. Debe transmitir el cambio a la propiedad $ rootScope para que todos los ámbitos secundarios conozcan el cambio y estén atentos a este cambio en la directiva.

Controlador:

$rootScope.countryMap = ''thiscountry_map''; $rootScope.$broadcast( "countryMapChanged", $rootScope.countryMap );

Directiva:

app.directive(''countrymapalt'', [function() { return { link: function(scope, element, attrs) { scope.$on("countryMapChanged", function(event, map) { setTimeout( function() { //function body here }, 100); }) } }; }]);


No se recomienda usar el alcance raíz para establecer y obtener propiedades en su aplicación angular. Intente utilizar $ cacheFactory, ya que de esa manera también puede almacenar en caché algunos valores en varias solicitudes. ( $ cacheFactory docs )


Otra forma es crear un servicio y lanzar ese servicio al $ rootScope y otras funciones. Lo hice así por mi entorno ...

app.service(''myService'', function ($rootScope) { this.removeItem = function (el) { console.log(''rootScope: '',$rootScope); return true; } }); app.directive(''draggable'', function($document,myService) { return function(scope, element, attr) { myService.removeItem({id:1}) } });

Si puedes, la mejor manera es la solución de Mike. si no, prueba mi solución.


Puedes hacerlo de esta manera:

{{$root.rsLabels.welcome}}