在运行时动态分配ng-controller

时间:2014-07-08 18:47:34

标签: javascript angularjs

我有一种情况需要动态更改控制器,以便相应地影响范围变量。一般结构:

<div ng-controller="GameController">
   // some general HTML which fits all types of games
    <div ng-controller="someScopeVar"> // Type of game
      // some game-type-specific ng-models that should respond to the change of controller, i.e scope
    </div
</div>

我看到here可以在ng-repeat内完成。可以在它之外完成吗? 换句话说,我可以告诉角度将其读作变量而不是字符串文字吗?

2 个答案:

答案 0 :(得分:3)

正如评论中所讨论的,angular有一个非常强大的功能/库来处理这些方案 - ui-router (强大的wiki

ui-router是开发功能性片段的必要答案 - 状态,而不是在视图/ url 中思考(从主页引用)

  

AngularUI路由器是AngularJS的路由框架,允许您将界面的各个部分组织到状态机。与Angular ngRoute模块中的 $ route 服务不同,Angular ngRoute模块围绕URL路由进行组织,UI-Router围绕状态进行组织,其中也可以选择包含路由作为其他行为,附​​上。

有一些非常有趣的博客文章:

  

......关于AngularJS新路由器最有趣的事情,不是路由器本身,而是随之而来的状态管理器。您可以定位一个州,而不是将控制器/视图定位为呈现给定的网址。国家在一个层面上进行管理,提供了父状态的继承和页面组件的复杂组合,同时保持了声明性......

  

... ui-router完全接受路由系统的状态机性质。它允许您定义状态,并过渡您的应用程序到这些状态。真正的胜利是它允许你解耦嵌套状态,并以优雅的方式做一些非常复杂的布局。

正是我们需要的点 - 解耦子状态...... 实际上动态更改控制器 ...可能是通过网址更改或只是状态更改(一个兄弟的孩子而不是其他没有网址更改)

  

你需要考虑一下你的路由方式有点不同,但是一旦你了解了基于状态的方法,我想你会喜欢它......

最后,链接很少,我将其标记为ui-router的圣杯

  • Sample application。在行动中我们可以看到,ui-router状态机如何工作。我们可以将列表加载为父状态,然后我们可以选择行项目,这些行项目代表他们自己的子状态 ...而父项是没有重新加载here我试图更详细地解释它)

  • state.js - 示例应用程序的基本代码段。这是我见过的最好的文档代码片段之一...花了一些时间来完成,这将为您提供80%的答案:ui-Router如何工作

根据我的经验,这非常适合小型应用程序以及大型系统......喜欢它......

答案 1 :(得分:2)

这对ngRepeat的作用方式不同。它起作用,因为它编译每个重复,这是你需要在这里做的。

例如:

mainCtrl = function($scope, $compile, $element) {
    $scope.someScopeVar = ctrl1;
    $scope.changeCtrl = function(id) {
        $scope.someScopeVar = id === 1 ? ctrl1 : ctrl2;
        var elm = $element.find('div');
        elm.replaceWith($compile(template)($scope));
    }
}

var ctrl1 = function($scope) { 
  $scope.name = 'World';
}

var ctrl2 = function($scope) {      
  $scope.name = 'John';
}

我们将每个控制器函数分配给$scope.someScopeVar,然后我们必须用新控制器编译一个新元素并替换旧元素。

我不相信angular有能力像这样快速更新控制器。对于新功能可能是一个好主意。

FIDDLE


另一个选择是使用mixin模式更新主范围。你没有获得新的闪亮范围,但它可能适用于你的目的。

mainCtrl = function($scope, $compile, $element) {
    angular.extend($scope, ctrl1());
    $scope.changeCtrl = function(id) {
         angular.extend($scope, id === 1 ? ctrl1() : ctrl2());
    }
}

var ctrl1 = function() { 
  var obj = {};
  obj.name = 'World';
  return obj;
}

var ctrl2 = function() {      
  var obj = {};
  obj.name = 'John';
  return obj;
}

FIDDLE