Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 使用ng控制器注入所需的依赖项_Angularjs_Angular Ui Router - Fatal编程技术网

Angularjs 使用ng控制器注入所需的依赖项

Angularjs 使用ng控制器注入所需的依赖项,angularjs,angular-ui-router,Angularjs,Angular Ui Router,使用ui.router,我们有一个状态控制器: controller('widget', function($repository, $stateParams){ $scope.widget = $repository.get($stateParams.id); }) 注册地址: .state('widget', controller: 'widget', template: '/widgetTemplate.html' 我们遇到了一种情况,我们希望将此控

使用ui.router,我们有一个状态控制器:

controller('widget', function($repository, $stateParams){
    $scope.widget = $repository.get($stateParams.id);
})
注册地址:

.state('widget',
       controller: 'widget',
       template: '/widgetTemplate.html'
我们遇到了一种情况,我们希望将此控制器作为模板的一部分进行重用:

<div ng-controller="widget" ng-include="/widgetTemplate.html"></div>

但似乎没有一种简单的方法可以将模拟的$stateParams对象注入正确的ID。类似于:

<div ng-controller="widget" ng-inject="{$stateParams: {id: 1234}}" ng-include="/widgetTemplate.html"></div>


除了编写一个自定义指令来扩充ng控制器或重构代码以利用继承的作用域之外,还有什么现成的方法可以做到这一点吗?

我认为没有现成的方法<代码>ng控制器只使用普通的控制器实例化,没有机会注入任何东西

但这是一个有趣的“特性”,实际上,可以用一个定制指令相对简单地构建它

下面是一个示例(免责声明:它肯定不会在模糊场景下进行测试):

用法如您所述:

<div ng-controller="MainCtrl">
  {{name}}
  <div ng-controller="SecondCtrl" ng-inject="{foo: name, bar: 'bar'}">
  </div>
</div>

在某些地方,我对状态和指令使用了控制器,看起来与您尝试执行的操作类似

您可以定义重新使用控制器和模板的指令。它将您希望从状态中设置的内容添加为作用域中可用的参数:

.directive('widget', function(){
  return {
    restrict: 'E',
    template: '<div>id in directive {{widgetId}}</div>',
    controller: 'widget',
    scope: {
      widgetId:'='
    }
  };
})
最后,您可以使用它通过特定id引用小部件:

<widget widget-id="789"></widget>

这里有一个plunker示例:

答案似乎是“没有现成的”方式。受这些反应的启发

用法:

<div ng-component="test.controller({$stateParams: { id: 1}})" template="test.html"></div>

<div ng-component="test.controller({$stateParams: { id: 2}})">
  <div>Transcluded Template ID: {{id}}</div>
</div>
我使用了实现uiSref的代码的修改版本(有时我希望angular能够将这些小金块作为公共API的一部分)


ngComponent是一种“轻量级”指令,可以在标记中声明,而无需实际构建指令。你可能会把它放远一点,但在某个时候,你无论如何都需要编写一个指令。

我也有同样的想法,但在我从头开始写东西之前,我想看看是否有现成的方法来完成它。你是怎么想出510作为优先级的?
ng控制器
在500这个答案也适用于我遇到的
ui路由
代码可恢复性问题。除非您尝试将控制器与不使用ui.router的模块一起重新使用,否则这是可行的。将没有要注入的$stateParams。我试图避免修改当前控制器代码。您可以使用$injector。必须检查$stateParams是否可用,但仍必须修改当前控制器代码。您可以使用
$templateRequest
而不是
$http
对,1.3之前不可用
.controller('widget', function($scope, $stateParams){
  $scope.widgetId = $scope.widgetId || $stateParams.id;
})
<widget widget-id="789"></widget>
<div ng-component="test.controller({$stateParams: { id: 1}})" template="test.html"></div>

<div ng-component="test.controller({$stateParams: { id: 2}})">
  <div>Transcluded Template ID: {{id}}</div>
</div>
.directive('ngComponent', function($compile, $parse, $controller, $http, $templateCache) {
return {
  restrict: 'A',
  transclude: true,
  scope: true,
  compile: function(tElement, tAttr) {
    return function(scope, element, attrs, ctrl, transclude) {

      //credit for this method goes to the ui.router team!
      var parseControllerRef = function(ref, current) {
        var preparsed = ref.match(/^\s*({[^}]*})\s*$/),
          parsed;
        if (preparsed) ref = current + '(' + preparsed[1] + ')';
        parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/);
        if (!parsed || parsed.length !== 4) throw new Error("Invalid component ref '" + ref + "'");
        return {
          controller: parsed[1],
          paramExpr: parsed[3] || null
        };
      };

      var ref = parseControllerRef(attrs.ngComponent);
      scope.$eval(ref.paramExpr);
      if(attrs.template) {
        $http.get(attrs.template, {cache: $templateCache}).then(function(result){
          var template = $compile(result.data)(scope);
          element.append(template);
        },
        function(err){
            //need error handling
        });
      }
      else {
          transclude(scope, function(clone) {
            element.append(clone);
          })
      }

      var locals = {
        $scope: scope
      }

      angular.extend(locals, scope.$parent.$eval(ref.paramExpr));
      var controller = $controller(ref.controller, locals);
      element.data("ngControllerController", controller);

      //future:  may even allow seeing if controller defines a "link" function or 
      //if the attrs.link parameter is a function.
      //This may be the point of demarcation for going ahead and writing a 
      //directive, though.

    };
   }
 };
})
.controller('test.controller', function($scope, $stateParams) {
    $scope.id = $stateParams.id;
})