尝试注入AngularJS控制器或服务

时间:2015-12-01 23:15:22

标签: angularjs

我的AngularJS应用程序中有一个`TreeListDataModel'工厂,它由仪表板小部件框架使用。

现在,我最初想要将另一项服务注入TreeListDataModel;但是,我在$rootScope和/或$scope上存储了一些重要对象。所以我决定将控制器注入TreeListDataModel

问题:我无法成功将新的WidgetLinkingCtrl注入“TreeListDataModel”工厂。

我的错误是:

       Unknown provider: WidgetLinkingCtrlProvider <- WidgetLinkingCtrl <- TreeListDataModel <- widgetDefinitions

我首先想到的是我的index.html文件引用的顺序,如下所示:

您可以看到dashboard-widget-controller.jsgadgetDataModel.js之前加载,但我收到了注射错误。

<!-- dashboard-ui core -->
<script src="app/components/dashboard/dashboard-widget-defs.js"></script>
<script src="app/components/dashboard/dashboard-directives.js"></script>
<script src="app/components/dashboard/dashboard-widget-controller.js"></script> 

<!-- WIDGET-LINKING-CONTROLLER HERE !!! -->
<script src="app/components/widget-linking/widget-linking-controller.js"></script>
<script src="app/js/directives.js"></script>

<!-- factories -->

<!-- *** TreeListDataModel factory included in gadgetDataModel.js *** -->
<script src="app/components/data-model-factories/gadgetDataModel.js"></script>

<script src="app/components/data-model-factories/widgetModels.js"></script>
<script src="app/components/dashboard/kendo-refresh-factory.js"></script>

<!-- custom controllers -->
<script src="app/components/main/main-controller.js"></script>

这是完整的TreeListDataModel

'use strict';

angular.module('myapp')
.factory('TreeListDataModel', function (WidgetDataModel, WidgetLinkingCtrl) {

function TreeListDataModel() {
}

TreeListDataModel.prototype = Object.create(WidgetDataModel.prototype);
TreeListDataModel.prototype.constructor = WidgetDataModel;

angular.extend(TreeListDataModel.prototype, {
  init: function () {
      // Kendo treelist is initialized in parseDataForTreeList() of gadget-settings-controller code

      var ds = new kendo.data.TreeListDataSource({  // init empty Kendo ds
	  data: [],
	  schema: {}
      });

      if (this.dataModelOptions.dataSource != undefined) {
	  // some code omitted...
	  this.dataModelOptions.dataSource = ds;
      }

      // KENDO TREELIST SELECT EVENT !!
      this.dataModelOptions.change = function (e) {
	  var row = this.dataItem(this.select());
	  
	  var parentObj = _.find(this.dataItems(), { id: row.parentId });	  
	  //WidgetLinkingCtrl.linkCharts(row, parentObj);
      },
      // dataModelOptions are re-assigned in 'GridSettingsCtrl' controller, and persisted in 'DashboardState' factory
      this.updateScope(this.dataModelOptions);

  },
  updateScope: function (data) {
      this.dataModelOptions = data;
  },
  destroy: function () {
      WidgetDataModel.prototype.destroy.call(this);
  }
});

return TreeListDataModel;
});

(function () {
    'use strict';

    angular.module('rage')
      .controller('WidgetLinkingCtrl', ['$rootScope', '$scope', '$timeout', 'kendoRefreshFactory', widgetLinking]);

    function widgetLinking($rootScope, $scope, $timeout, kendoRefreshFactory, widgetLinking) {

        function linkCharts(row, parentRow) {
            var r = $rootScope;
            if (parentRow == undefined) {
                // user clicked on root node of grid/treelist
            }

        }
    }
})();

同样,如果你可以帮我弄清楚为什么我在注射WidgetLinkingCtrl时会出现注射错误,我将不胜感激。

的问候,

鲍勃

1 个答案:

答案 0 :(得分:1)

在MVW方法中,用于AngularJS,&#34;控制器&#34;控制其他(可注射)对象。您无法将控制器注入服务。但是,您可以注入服务介绍控制器。

因此在您的示例中,可能的解决方案之一是公开回调挂钩并在此挂钩中注册您的控制器功能。

TreeListDataModel:

this.dataModelOptions.change = function (e) {
  var row = this.dataItem(this.select());

  var parentObj = _.find(this.dataItems(), { id: row.parentId });     
  if (this.onChanged) this.onChanged(row, parentObj);
},

WidgetLinkingCtrl:

  function WidgetLinkingCtrl($scope, TreeListDataModel) {
     TreeListDataModel.onChanged = function(row, parentObj) {
       ... // do something 
    }
    $scope.$on('$destroy', function() {
       TreeListDataModel.onChanged = nil; // don't forget to unregister controller, otherwise you can have memory leak
    }
  }

因此,反转依赖性可以直接与调用控制器的方法具有相同的功能。