在AngularJS中实例化和初始化控制器

时间:2013-10-01 18:31:19

标签: javascript angularjs controller

我在使用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”时,文本“New type”(在控制器中初始化)不会出现。

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

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

由于

3 个答案:

答案 0 :(得分:5)

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

在这种情况下,我会使用AlkeTypeDefController指令创建ng:controller,因此您不需要以编程方式创建控制器,因为那时您需要将它附加到视图中,这就是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将为每个$scope创建一个新的typedef。然后AlkeTypeDefController用函数和值装饰该范围。

我希望它有所帮助

答案 1 :(得分:1)

当你调用$ controller(“AlkeTypeDefController”)时,它基本上会在AlkeTypeDefController构造函数上调用new并返回返回值而不是范围。您将name attrubute分配给范围,因此当您拥有typedef.name时,不会在html中访问它。

尝试将AlkeTypeDefController更改为:

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

然后你可以用var controller = $controller("AlkeTypeDefController");实例化它,你不必担心创建嵌套的范围。

答案 2 :(得分:1)

如果我得到你正确的说法,那么我想我会尝试利用自定义指令的强大功能,而不是动态生成控制器。

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>

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