0

我想知道在控制器之间共享指令 的好方法是什么。 我有即两个指令在不同的控制器 使用不同的配置我使用像想到 先觉得:angularjs共享控制器之间的数据配置

//html 
<body data-ng-controller="MainCtrl"> 
    <div class="container"> 
     <div data-ui-view></div> 
    </div> 
</body> 

//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) { 

}) 

这样我可以使用所有的功能在我的孩子控制器 但我不不太喜欢碰撞问题。 因为你不能使用服务(不能使用在服务$范围)的其他替代品可能会作出其他指令或把代码在运行块 但它使用父控制器等等 什么做的完全一样你想想吗?

UPDATE

您对这种方法有什么看法?

//outside of angular stauff 
function MyTest(){ 
    this.testScope = function(){ 
     console.log('It works'); 
    } 
} 

//inside a controller 
$scope.ns = new MyTest(); 

//in the view 
<p ng-click="ns.testScope()">ppp</p> 

RIUPDATE 这似乎是最好的选择:)

MyTest.call($scope); 

回答

6

考虑这篇文章所描述的方法:Extending AngularJS Controllers Using the Mixin Pattern

与其模仿你的方法出了服务的,创建一个包含这些方法基本控制器,然后调用延长你的派生控制器在将它们混合的例如,从岗位:

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); 
    }; 
} 

现在,我们可以混入AnimalController到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. 
    } 
} 

一ND那么在我们的模板中使用DogController:

<section ng-controller="DogController"> 
    <p>Dog</p> 

    <!-- Scope property mixin, displays: 'color: solid black' --> 
    <p ng-bind-template="color: {{ color }}"></p> 

    <!-- Calls an instance method mixin, outputs: 'BARK BARK!' --> 
    <button class="btn" ng-click="bark()">Bark Dog</button> 

    <!-- Scope method mixin, outputs: 'run speed: 35mph' --> 
    <button class="btn" ng-click="run()">Run Dog</button> 
</section> 

在本例中的控制器都在全球空间和包含在标记如下。

<script type="text/javascript" src="lib/jquery.js"></script> 
<script type="text/javascript" src="lib/angular.js"></script> 
<script type="text/javascript" src="app/controllers/animal-controller.js"></script> 
<script type="text/javascript" src="app/controllers/dog-controller.js"></script> 
<script type="text/javascript" src="app/controllers/cat-controller.js"></script> 
<script type="text/javascript" src="app/app.js"></script> 

我没有测试过,但我不明白为什么以下是行不通的:

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. 
    } 
}]); 

看到:docs为$控制器服务

+0

这就是我正在寻找的感谢:) – Whisher

+0

第二想法如何做到这一点,而不使用全局定义的控制器定义? – Whisher

+0

在示例回购中,它们是全局定义的https://github.com/bparvizi/angular-js-controller-mixins。但是他们没有理由必须考虑如何将控制器与browserify结合使用。但是,基本控制器必须定义在:http://ethanway.com/angular-and-browserify/。 mixin的要点。 –

3

你需要的是可怕的。

你不希望你的控制器来了解对方任何事情,更何况,有机会获得其他的功能之一。你可以使用服务来实现这一点。至于使用指令,不知道你想要发生什么。

至于你的第二件事情,你可以很容易地做到这一点

.service('MyTestService', function(){ 
    return { 
     testScope: function(){ 
      console.log('It works'); 
     } 
    }; 
}) 

.controller('MyController', ['$scope', 'MyTestService', function($scope, MyTestService){ 
    $scope.testScope = MyTestService.testScope; 
}]) 

,并在您的视图:

<p ng-click="testScope()">ppp</p> 
+0

感谢约MyTest.call($范围)的point.What;它似乎相当整洁,因为解决方案... – Whisher

+1

我对任何包含全局作用域对象的任何事情都很烦躁,但是,只要获得$ scope成为正确的东西,它就会工作。您可以将该模式用于烟雾测试目的,但我不会在生产代码中使用它。 –

+0

我添加了回复 – Whisher

0

我结束了:

//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; 
     }); 

我这样做因为我必须在创建帖子和编辑帖子中做同样的事情,但总的来说 我有相同的重复的公司德! :)

唯一的好处是代码已经减少了逻辑。

0

明显,但辉煌的解决方案(可能是)

(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){ 

      }); 

这很容易,干净,看不出任何缺点(这不是全球)

UPDATE

'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'; 
       }); 

一点点整洁和它的作品CIP CIP :)

+0

缺点是您使用$ rootScope作为父控制器 - 如果您想要多个父控制器会发生什么?如果将角度模块中的父控制器定义为控制器,然后使用$控制器服务将其实例化,则会更清晰。我会用一个例子更新我的答案,这样你就能明白我的意思了。 –

+0

我再次更新:)谢谢你的观点。你怎么看 ?我只是简化你的代码 – Whisher

+0

我记得你http://stackoverflow.com/questions/21464810/angular-extend-scope-is-it-safe – Whisher

相关问题