在运行时动态分配ng-controller

Dynamically assign ng-controller on runtime

本文关键字:ng-controller 动态分配 运行时      更新时间:2023-09-26

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

<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>

我在这里看到它可以在ng-repeat中完成。它能在它之外完成吗?换句话说,我能告诉angular将其作为变量而不是字符串文本来读取吗?

正如评论中讨论的那样,angular有一个非常强大的特性/库来处理这些场景- ui-router (与其强大的wiki)

ui-router是需要开发功能块的答案- 状态,而不是在view/url (引用自主页):

AngularUI Router是AngularJS的一个路由框架,它允许你把接口的各个部分组织成一个状态机。不像Angular ngRoute模块中的$route服务是围绕URL路由组织的,UI-Router是围绕状态组织的,可以选择附加路由和其他行为。

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

    AngularJS State Management with ui-router

…关于AngularJS的新路由器,最有趣的不是路由器本身,而是它附带的状态管理器。你的目标不是一个控制器/视图来呈现给定的url,而是一个状态。状态在层次结构中进行管理,提供父状态的继承和页面组件的复杂组合,同时本质上保持声明性…

    在AngularJS中使用ui-router的基础(by Joel Hooks)

ui-router完全支持路由系统的状态机特性。它允许您定义状态,并应用程序转换到这些状态。真正的优点是它允许您解耦嵌套状态,并以一种优雅的方式执行一些非常复杂的布局。

正是我们需要的——解耦子状态…动态更改控制器实际上…可以通过url更改或只是状态更改(一个兄弟姐妹的孩子而不是其他没有url更改)

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

最后,有几个链接,我将其标记为ui-router的圣杯

  • 示例应用程序。在操作中,我们可以看到ui-router状态机是如何工作的。我们可以加载list作为父状态,然后我们可以选择行项,它们代表它们自己的子状态…而父节点没有重新加载(这里我试图更详细地解释它)

  • state.js —示例应用程序的基本代码段。这是我见过的记录最好的代码片段之一……花了一些时间去看,这将给你80%的答案:ui-Router是如何工作的

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

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有能力像这样动态地更新控制器。可能是一个新功能的好主意。

小提琴


另一个选择是使用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;
}

小提琴