【问题标题】:Instantiate and initialize controller in AngularJS在 AngularJS 中实例化和初始化控制器
【发布时间】:2013-10-01 18:31:19
【问题描述】:

我在使用 Angular 实例化控制器时遇到问题。我有一个主控制器 AlkeTypeDefListController,我想从中动态创建/删除 AlkeTypeDefController 类型的控制器,所以我已经这样做了:

AlkeTypeDefListController的代码:

//  Create main controller          
Alke.controller('AlkeTypeDefListController', ['$scope', '$controller', function($scope, $controller)
{
    var primitives = 
    [

    ];

    //  Add some properties to the scope
    angular.extend($scope,
    {
        typedefs        : primitives,
        addTypeDef      : function()
        {            
            var controller = $controller("AlkeTypeDefController", {$scope:$scope.$new()});
            $scope.typedefs.push(controller);
        }             
    });   
}]);

AlkeTypeDefController的代码:

//  Create main controller          
Alke.controller('AlkeTypeDefController', ['$scope', '$controller', function($scope, $controller)
{
    //  Add some properties to the scope
    angular.extend($scope,
    {
        name            : "New Type",
        fields          : [],
        addField        : function()
        {

        }  
    });  
}]);

html代码是这样的:

<div id="typedefs-editor" ng:controller="AlkeTypeDefListController">
    <button ng:click="addTypeDef()">Add</button>
    <button>Remove</button>
    <div id="typedef-list">
        <ul class="list">
        <li ng:repeat="typedef in typedefs"><a href="#">{{typedef.name}}</a></li>                               
        </ul>
    </div>
</div>

问题并不是真正来自于实例化(它工作正常),而是来自于初始化。事实上,当我按下“添加”按钮时出现新的“li”时,文本“新类型”(在控制器中初始化)并没有出现。

我认为它与范围或类似的东西有关,但我真的找不到如何解决这个问题。

我想知道这种方法是否正确,以及如何解决我遇到的问题。

谢谢

【问题讨论】:

    标签: javascript angularjs controller


    【解决方案1】:

    阅读代码,我了解到您想动态创建typedefs,而那些typedef 项目必须由AlkeTypeDefController 控制。

    在这种情况下,我将使用ng:controller 指令创建AlkeTypeDefController,因此您不需要以编程方式创建控制器,因为您需要将它附加到视图,而这正是ngController 指令为你做。

    注意AlkeTypeDefListController 不会创建AlkeTypeDefController 控制器,这是在视图中完成的

    Demo on Plunker

    控制器:

    .controller('AlkeTypeDefListController', ['$scope', function($scope) {
        var primitives = [];
    
        $scope.typedefs = primitives;
    
        $scope.addTypeDef = function() { 
          var typeDef = { name: 'New Type' };
          $scope.typedefs.push(typeDef);
        }
    }])
    
    .controller('AlkeTypeDefController', ['$scope', function($scope) {
        $scope.addField = function() {
          alert('add Field');
        }
    }]);
    

    查看 (注意ng-controller 指令是如何在li 元素中指定的):

    <div id="typedefs-editor" ng:controller="AlkeTypeDefListController">
      <button ng:click="addTypeDef()">Add</button>
      <button>Remove</button>
      <div id="typedef-list">
    
      <ul class="list">
          <li ng:repeat="typedef in typedefs" ng:controller="AlkeTypeDefController">
            <a href="#" ng-click="addField()">{{typedef.name}}</a>            
          </li>                               
      </ul>
    </div>
    

    在上面的代码中,ngRepeat 将为每个typedef 创建一个新的$scopeAlkeTypeDefController 然后用函数和值装饰该范围。

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      当您调用 $controller("AlkeTypeDefController") 时,它实际上会在 AlkeTypeDefController 构造函数上调用 new 并返回返回值而不是范围。您将name 属性分配给范围,因此当您拥有typedef.name 时,它不会在您的html 中被访问。

      尝试将您的 AlkeTypeDefController 更改为:

      Alke.controller('AlkeTypeDefController', function() {
          this.name = "New Type";
          this.fields = [];
          this.addField = function() {};
      });
      

      然后您可以使用:var controller = $controller("AlkeTypeDefController"); 对其进行实例化,您不必担心创建嵌套范围。

      【讨论】:

        【解决方案3】:

        如果我的理解正确,那么我想我会尝试在这里利用自定义指令的强大功能,而不是动态生成控制器。

        plunker

        控制器:

        Alke.controller('alkeTypeDefListController', ['$scope', '$controller',
          function($scope, $controller) {
            var primitives = [];
            var addTypeDef = function() {
              $scope.typedefs.push({
                name: 'new name'
              });
            };
            var removeTypeDef = function(){
              $scope.typedefs.pop();
            };
        
            var properties = {
              typedefs: primitives,
              addTypeDef: addTypeDef,
              removeTypeDef: removeTypeDef
            };
        
            //  Add some properties to the scope
            angular.extend($scope, properties);
          }
        ]);
        

        指令:

        Alke.directive('alkeTypeDef', function() {
          return {
            restrict: 'A',
            scope: {
              typeDef: '=alkeTypeDef'
            },
            template: '<a href="#">{{typeDef.name}}</a>',
            link: function(scope, element, attr) {
              var properties = {
                fields: [],
                addField: function() {
        
                }
              };
        
              angular.extend(scope, properties);
            }
          };
        });
        

        HTML:

        <div ng-app='Alke'>
          <div id="typedefs-editor" ng-controller="alkeTypeDefListController">
            <button ng-click="addTypeDef()">Add</button>
            <button ng-click="removeTypeDef()">Remove</button>
            <div id="typedef-list">
              <ul class="list">
                <li alke-type-def='typedef' ng-repeat="typedef in typedefs"></li>
              </ul>
            </div>
          </div>
        </div>
        

        如果你想要一个控制器,那么你可以在指令中使用一个而不是链接函数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-18
          • 2013-10-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多