Angularjs compartilhar dados de configuração entre controladores

Eu estou querendo saber o que poderia ser uma boa maneira de compartilhar diretiva entre o controlador. Eu tenho duas diretivas para usar em um controlador diferente com configuração diferente, a primeira coisa que pensei em usar como:

//html  
//js .controller('MainCtrl', function ($scope,$upload) { /*File upload config*/ $scope.onFileSelect = function($files) { for (var i = 0; i < $files.length; i++) { var file = $files[i]; $scope.upload = $upload.upload({ url: 'server/upload/url', method: 'POST', data: {myObj: $scope.myModelObj}, file: file, }).progress(function(evt) { console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total)); }).success(function(data, status, headers, config) { console.log(data); }); } }; /* Datepicker config */ $scope.showWeeks = true; $scope.minDate = new Date(); $scope.open = function($event) { $event.preventDefault(); $event.stopPropagation(); $scope.opened = true; }; $scope.dateOptions = { 'year-format': "'yy'", 'starting-day': 1 }; $scope.format = 'MMM d, yyyy'; }) .controller('IndexCtrl', function ($scope) { })

Ao fazê-lo, posso usar todas as funções do meu controlador de crianças, mas não gosto muito de problemas de colisão. Desde que você não pode usar um serviço (você não pode usar o $ escopo em um serviço) as outras alternativas poderiam fazer uma outra diretiva ou colocar o código em um bloco de execução, mas é o mesmo usando um controlador pai, então o que você pensa sobre ?

ATUALIZAR

O que você acha dessa abordagem?

 //outside of angular stauff function MyTest(){ this.testScope = function(){ console.log('It works'); } } //inside a controller $scope.ns = new MyTest(); //in the view 

ppp

RIUPDATE esta parece ser a melhor opção 🙂

 MyTest.call($scope); 

Considere o método descrito por este post: Estendendo os controladores AngularJS usando o padrão Mixin

Em vez de copiar seus methods de um serviço, crie um controlador de base que contenha esses methods e, em seguida, call extend em seus controladores derivados para misturá-los. O exemplo do post:

 function AnimalController($scope, vocalization, color, runSpeed) { var _this = this; // Mixin instance properties. this.vocalization = vocalization; this.runSpeed = runSpeed; // Mixin instance methods. this.vocalize = function () { console.log(this.vocalization); }; // Mixin scope properties. $scope.color = color; // Mixin scope methods. $scope.run = function(){ console.log("run speed: " + _this.runSpeed ); }; } 

Agora podemos misturar o AnimalController no DogController:

 function DogController($scope) { var _this = this; // Mixin Animal functionality into Dog. angular.extend(this, new AnimalController($scope, 'BARK BARK!', 'solid black', '35mph')); $scope.bark = function () { _this.vocalize(); // inherited from mixin. } } 

E então use o DogController em nosso template:

 

Dog

Os controladores neste exemplo estão todos no espaço global e estão incluídos na marcação da seguinte maneira.

       

Eu não testei, mas não vejo por que o seguinte não funcionaria:

 var myApp = angular.module('myApp', []) .controller('AnimalController', ['$scope', 'vocalization', 'color', 'runSpeed', function ($scope, vocalization, color, runSpeed) { /* controller code here */}]); .controller('DogController', ['$scope', '$controller', function($scope, $controller) { var _this = this; // Mixin Animal functionality into Dog. angular.extend(this, $controller('AnimalController', { $scope: scope, vocalization: 'BARK BARK!', color: 'solid black', runSpeed:'35mph' })); $scope.bark = function () { _this.vocalize(); // inherited from mixin. } }]); 

consulte: docs para o serviço $ controller

O que você quer é terrível.

Você não gostaria que seus controladores soubessem nada um do outro, quanto mais um ter access à function do outro. Você pode apenas usar um serviço para conseguir isso. Quanto ao uso de diretivas, não sei exatamente o que você quer que aconteça.

Quanto à sua segunda coisa, você pode facilmente fazer isso

 .service('MyTestService', function(){ return { testScope: function(){ console.log('It works'); } }; }) .controller('MyController', ['$scope', 'MyTestService', function($scope, MyTestService){ $scope.testScope = MyTestService.testScope; }]) 

e na sua opinião:

 

ppp

Acabei com:

 //service .service('PostUploader',function($upload){ var that = this; var fileReaderSupported = window.FileReader !== null; this.notify = null; this.success = null; this.showAlert = false; this.avatar = ''; this.onFileSelect = function($files) { var $file = $files[0]; var filename = $file.name; this.avatar = filename; var isImage = /\.(jpeg|jpg|gif|png)$/i.test(filename); if(!isImage){ this.showAlert = true; return; } this.showAlert = false; if (fileReaderSupported && $file.type.indexOf('image') > -1) { var fileReader = new FileReader(); fileReader.readAsDataURL($file); fileReader.onload = that.notify; } $upload.upload({ url :'/api/post/upload', method: 'POST', headers: {'x-ng-file-upload': 'nodeblog'}, data :null, file: $file, fileFormDataName: 'avatar' }) .success(that.success) .progress(function(evt) { }) .error(function(data, status, headers, config) { throw new Error('Upload error status: '+status); }) }; this.closeAlert = function() { this.showAlert = false; }; }) //controller /* Uploader post */ $scope.dataUrl = null; $scope.avatar = PostUploader.avatar; $scope.showAlert = PostUploader.showAlert; $scope.onFileSelect = PostUploader.onFileSelect; $scope.closeAlert = PostUploader.closeAlert; PostUploader.notify = function(e){ $timeout(function() { $scope.dataUrl = e.target.result; }); }; PostUploader.success = function(data, status, headers, config) { $timeout(function() { $scope.post.avatar = data.url; }); } $scope.$watch('avatar',function(newVal, oldVal){ if(newVal) { $scope.avatar = newVal; } }); $scope.$watch('showAlert',function(newVal, oldVal){ $scope.showAlert = newVal; $scope.dataUrl = null; }); 

Eu fiz isso porque eu tenho que fazer a mesma coisa em criar post e editar post, mas apesar de tudo eu tenho o mesmo código repetido! 🙂

A única coisa boa é que o código tem menos lógica.

solução óbvia mas shiny (pode ser)

 (function(window, angular, undefined) { 'use strict'; angular.module('ctrl.parent', []) .run(function ($rootScope) { $rootScope.test = 'My test' $rootScope.myTest = function(){ alert('It works'); } }); })(window, angular); angular.module('app',['ctrl.parent']) .controller('ChildCtrl', function($scope){ }); 

É fácil e limpo e não vejo nenhuma desvantagem (não é global)

ATUALIZAR

 'use strict'; (function(window, angular, undefined) { 'use strict'; angular.module('ctrl.parent', []) .controller('ParentController',function (scope) { scope.vocalization = ''; scope.vocalize = function () { console.log(scope.vocalization); }; }); })(window, angular); angular.module('app',['ctrl.parent']) .controller('ChildCtrl', function($scope,$controller){ angular.extend($scope, new $controller('ParentController', {scope:$scope})); $scope.vocalization = 'CIP CIP'; }); 

apenas um pouco mais limpo e funciona CIP CIP 🙂