将依赖项添加到AngularJS控制器

时间:2016-03-22 19:09:32

标签: angularjs dependency-injection controller

我继承了一些AngularJS代码。它有这个

function MainCtrl($scope) 
{
  // code goes here
};

angular
    .module('inspinia')
    .controller('MainCtrl', MainCtrl)

现在我想添加一个自定义控制器,它将一个datepicker和timepicker组合成一个控件。 GitHub项目是here,还有一个演示Plunk here

演示Punk将其控制器声明为

var app = angular.module('app', ['ui.bootstrap', 'ui.bootstrap.datetimepicker']);

app.controller('MyController', ['$scope', function($scope) {

如何将其添加到现有控制器中?合并声明是什么?最好是我可以在ng-stricti-di上使用ng-app

[更新]这是我最好的猜测,在10个小时左右回家之前我无法测试。它看起来怎么样?

var myApp=angular.module('myApp', ['$scope','ui.bootstrap','ui.bootstrap.datetimepicker']); 

myApp.controller('MainCtrl', function($scope) 
{
    // code goes here, and can use ui.bootstrap and ui.bootstrap.datetimepicker
    // which were injected into the app's module
}]);

[更新2 [当我将其更改为

angular
    .module('inspinia' ['ui.bootstrap', 'ui.bootstrap.datetimepicker'])
        .controller('MainCtrl', MainCtrl)

我得到了

错误:[$ injector:nomod] http://errors.angularjs.org/1.5.0/ $ injector / nomod?p0 = undefinedError:[$ injector:nomod] http://errors.angularjs.org/1.5.0/ $ injector / nomod?p0 = undefined

Despue index.html

<script src="js/bootstrap/bootstrap.min.js"></script>

如何让这个项目使用ui boostrap及其datepicker?

3 个答案:

答案 0 :(得分:4)

请查看以下步骤:

  1. 您不需要在应用声明中注入$ scope 注入要使用的外部模块,对于这种情况: 'ui.bootstrap'和'ui.bootstrap.datetimepicker'。

    angular.module('myApp', ['ui.bootstrap','ui.bootstrap.datetimepicker'])
    
      

    合并声明是什么?

    因为'ui.bootstrap.datetimepicker'仅依赖于'ui.bootstrap.dateparser''ui.bootstrap.position'但您还需要包含在 ui.bootstrap-tpls.js 中的引导程序模板和功能。

  2. 确保包含index.html

    中所需的上述文件
    <link rel="stylesheet" ref="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />     
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.0/ui-bootstrap-tpls.js"></script>
    <!-- make sure you download this file from the github project -->
    <script src="datetime-picker.js"></script>
    
  3.   

    如何将其添加到现有控制器中?

    当您声明控制器时,它会继承您为应用声明(注入)的所有模块依赖关系,因此您不需要再次执行此操作。在你的控制器中,你应该创建一个对象文字来存储为用户选择的日期时间,并创建一个变量来控制日期选择器何时打开,如下所示:

    angular.module('myApp').controller('MainCtrl', ['$scope', function($scope) {
     $scope.myDatetime = {
       dateSelected: new Date(),
       isOpen: false
     }
    }]);
    
  4. 在html中调用日期时间选择器指令:

    <html ng-app-="myApp">
    <head> .... </head>
    <body ng-controller="MainCtrl">
    <div class="input-group">
       <input type="text" class="form-control" datetime-picker="MM/dd/yyyy HH:mm" ng-model="myDatetime.dateSelected" is-open="myDatetime.isOpen" />
        <span class="input-group-btn">
           <button type="button" class="btn btn-default" ng-click="myDatetime.isOpen = !myDatetime.isOpen"><i class="fa fa-calendar"></i></button>
        </span>
    </div>
    </body>
    </html>
    

    我希望这对你有帮助。

答案 1 :(得分:3)

根据你在问题下的评论,你的困惑在于两段代码处理依赖注入的方式。所以在我走得更远之前,如果你还没有阅读documentation on dependency injection,那么就在这里停下来阅读它。它将包含您的所有答案以及更多内容,如果处理Angular超过五分钟,您需要知道这些内容。

要回答您所遇到的具体情况,您列出的顶级代码会对控制器使用隐式注入,但对于缩小操作不安全,也不推荐使用。您找到的代码示例使用控制器的数组依赖注入,这对于缩小是更好和安全的。第二个示例中的app声明只是标准的模块依赖注入,不应该与您在应用程序中已有的不同。

因此,要使用您发现的代码,您只需向应用程序添加正确的模块依赖项,例如:

angular.module('inspinia', ['ui.bootstrap', 'ui.bootstrap.datetimepicker']);
angular.module('inspinia').controller('MainCtrl',MainCtrl);
function MainCtrl($scope) { }

您的控制器似乎已经具有正确的依赖关系,因此不需要更改(也就是说它不需要$scope之外的任何内容)。我使用了您的第一个示例中的代码来显示您当前的代码将如何更新,但理想情况下,您将为控制器使用第二版依赖注入。

您对错误的更新是因为ui.bootstrap模块不是引导程序的一部分,而是angular-bootstrap project的一部分。您需要在页面中包含这些j。

如果我没有继续并且提到使用$inject服务进行依赖注入的第三种方法,那将是我的疏忽。它在popular style guides中是优选的,因为使用任务运行器来自动化很容易。由于这个原因,这可以说是最好的选择。

答案 2 :(得分:1)

这是最小的应用程序,您需要使用此日期选择器

HTML:                                      

<body ng-app="inspinia">
  <div ng-controller="MainCtrl as ctrl">
    <h1>Datepicker Demo</h1>
    <div class="row">
      <div class="col-md-6">
        <p class="input-group">
          <input type="text" class="form-control" uib-datepicker-popup ng-model="ctrl.dt" is-open="ctrl.opened" close-text="Close" />
          <span class="input-group-btn">
              <button type="button" class="btn btn-default" ng-click="ctrl.open()"><i class="glyphicon glyphicon-calendar"></i></button>
            </span>
        </p>
      </div>
    </div>
  </div>
</body>

JavaScript的:

(function() {
  'use strict';
  angular.module('inspinia', ['ui.bootstrap']);
  angular.module('inspinia').controller('MainCtrl', MainCtrl);

  function MainCtrl() {

    this.open = function() {
      this.opened = true;
    };

    this.opened = false;
  }
})();

我在这里为你创建了一个plunker,所以你可以尝试:

http://plnkr.co/edit/jEwT39sKcKtr8jbQa0uc?p=preview