简体   繁体   English

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

[英]Instantiate and initialize controller in AngularJS

I have a problem instanciating controller with Angular. 我有一个问题是使用Angular实现控制器。 I have a main controller AlkeTypeDefListController from which I want to dynamically create/remove controllers of type AlkeTypeDefController , so I have done that : 我有一个主控制器AlkeTypeDefListController ,我想从中动态创建/删除AlkeTypeDefController类型的控制器 ,所以我做到了:

Code of AlkeTypeDefListController : 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);
        }             
    });   
}]);

Code of AlkeTypeDefController : 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()
        {

        }  
    });  
}]);

The html code is this one: 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>

The problem does not really come from the instantiation (which works fine), but from the initialization. 问题并非真正来自实例化(工作正常),而是来自初始化。 In fact, when the new "li" appears when I push the "Add" button, the text "New type" (initialized in the controller) does not appear. 实际上,当我按下“添加”按钮时出现新的“li”时,文本“New type”(在控制器中初始化)不会出现。

I think it is about the scope or something like that, but I can't really find how to fix this. 我认为这是关于范围或类似的东西,但我真的无法找到如何解决这个问题。

I wanted to know if this method seems correct, and also how could I fix the problem I have. 我想知道这种方法是否正确,以及如何解决我遇到的问题。

Thanks 谢谢

Reading the code, I understand that you want to create typedefs dynamically and those typedef items have to be controlled by an AlkeTypeDefController . 阅读代码,我知道你想动态创建typedefs ,那些typedef项必须由AlkeTypeDefController控制。

In that case I would create AlkeTypeDefController using ng:controller directive, so you don't need to create the controller programmatically, because then you would need to attached it to the view and that's just what the ngController directive does for you. 在这种情况下,我将使用ng:controller指令创建AlkeTypeDefController ,因此您不需要以编程方式创建控制器,因为您需要将它附加到视图,这正是ngController指令为您所做的。

Notice AlkeTypeDefListController does not create a AlkeTypeDefController controller, this is done in the view 注意AlkeTypeDefListController不会创建AlkeTypeDefController控制器,这在视图中完成

Demo on Plunker 关于Plunker的演示

Controllers: 控制器:

.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');
    }
}]);

View (notice how ng-controller directive is specified in li element): 查看 (注意如何在li元素中指定ng-controller指令):

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

In the code above, ngRepeat is going to create a new $scope for each typedef . 在上面的代码中, ngRepeat将为每个typedef创建一个新的$scope AlkeTypeDefController then decorates that scope with functions and values. 然后AlkeTypeDefController用函数和值装饰该范围。

I hope it helps 我希望它有所帮助

When you call $controller("AlkeTypeDefController") it will essentially call new on the AlkeTypeDefController constructor and give you back the return value not the scope . 当你调用$ controller(“AlkeTypeDefController”)时,它基本上会在AlkeTypeDefController构造函数上调用new ,并返回返回值而不是范围 You are assign the name attrubute to the scope though so it is not being accessed in your html when you have typedef.name . 您将name attrubute分配给范围,因此当您拥有typedef.name时,不会在html中访问它。

Try changing your AlkeTypeDefController to this: 尝试将AlkeTypeDefController更改为:

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

Then you can instantiate it with: var controller = $controller("AlkeTypeDefController"); 然后你可以使用: var controller = $controller("AlkeTypeDefController");实例化它var controller = $controller("AlkeTypeDefController"); and you shouldn't need to worry about creating nested scopes. 而且您不必担心创建嵌套范围。

If I get what you're saying correctly then I think I'd try to leverage the power of a custom directive here instead of dynamically generating controllers. 如果我得到你说的正确,那么我想我会尝试利用自定义指令的强大功能,而不是动态生成控制器。

plunker plunker

Controller: 控制器:

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);
  }
]);

Directive: 指示:

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

If you want a controller then you can use one in the directive instead of a linking function. 如果你想要一个控制器,那么你可以在指令中使用一个而不是一个链接函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM