【问题标题】:Angular TypeScript state controllerAngular TypeScript 状态控制器
【发布时间】:2015-12-21 14:51:47
【问题描述】:

我正在尝试将控制器附加到状态(使用角度 ui.router),但我不明白为什么以一种方式编写它,而另一种方式则不行。

工作示例(控制器针对模块注册):

this.$stateProvider
  .state('items', {
    url: '/{cluster}/items',
    templateUrl: App.mapPath('Items/Items.html'),
    controller: 'ItemsController as controller'
   });

但这没有(使用“匿名”控制器):

this.$stateProvider
  .state('items', {
    url: '/{cluster}/items',
    templateUrl: App.mapPath('Items/Items.html'),
    controller: ItemsController,
    controllerAs: 'controller'
  });

请记住,我的控制器具有依赖项:

export class ItemsController {
  static $inject = ['$scope', 'itemsResource', '$stateParams'];
  constructor(
    scope: IItemsScope,
    itemsFactory: IItemsResource,
    stateParams: IClustersStateParams) {
     scope.items = itemsFactory.query({ cluster: stateParams.cluster });
   }

  public newItem(): void {
    console.log('test');
  }
}

我的 Items.html 模板是:

<div class="items">
  <ul class="add">
    <li>
      <action icon-style="glyphicon-plus" text="Add new item" activated="controller.newItem()"></action>
    </li>
  </ul>
  <ul>
    <li ng-repeat="item in items">
      <item item="item"></item>
    </li>
  </ul>
  </div>

还有action 指令:

export class ActionDirective implements ng.IDirective {
  restrict = 'E';
  replace = true;
  template = '<a class="action"><span class="glyphicon {{iconStyle}}" aria-hidden="true"></span><span>{{text}}</span></a>';
  scope = {
    iconStyle: '@iconStyle',
    text: '@text',
    activated: '&'
  };

  public link(scope: IActionDirectiveScope, instanceElement: ng.IAugmentedJQuery, instanceAttributes: ng.IAttributes, controller: any): void
  {
    instanceElement.on('click', (): void => {
    scope.activated();
    });
  }

public static factory(): ng.IDirectiveFactory {
  const directive = () => new ActionDirective();

  return directive;
}

}

问题是controller.newItem() 电话。在工作示例中,它将正常工作,否则它不会向控制台显示任何内容。此外,我注意到items 数组(在控制器的构造函数中设置)将始终被填充(无论采用何种方法),因此只需调用controller.newItem() 就行不通了...

【问题讨论】:

    标签: angularjs typescript angular-ui-router


    【解决方案1】:

    您应该将控制器作为字符串名称传递:

    this.$stateProvider
      .state('items', {
        url: '/{cluster}/items',
        templateUrl: App.mapPath('Items/Items.html'),
        //controller: ItemsController,
        controller: "ItemsController",
        controllerAs: 'controller'
      })
    

    如文档 http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$stateProvider 中所述

    controller:控制器fn,应该与新相关范围相关联或已注册控制器的名称(如果作为字符串传递)。可选地,可以在此处声明 ControllerAs。

    但我们也可以只路径构造函数(类名)。

    a working example

    我将控制器放入命名空间:

    namespace MyModule{
     export class ItemsController {
      static $inject = ['$scope', 'itemsResource', '$stateParams'];
      constructor(
        scope: IItemsScope,
        itemsFactory: IItemsResource,
        stateParams: IClustersStateParams) {
         scope.items = itemsFactory.query({ cluster: stateParams.cluster });
       }
    
      public newItem(): void {
        console.log('test');
      }
     }
    }
    

    查看it here

    在这个状态下定义:

    .state('items', {
        url: '/{cluster}/items',
        //templateUrl: App.mapPath('Items/Items.html'),
        templateUrl: 'Items/Items.html',
        controller: MyModule.ItemsController, 
        controllerAs: 'controller'
    })
    

    还有这个视图Items/Items.html

    <div class="items">
     ...
          <button icon-style="glyphicon-plus" text="Add new item" >xxx
     ..
    </div>
    

    我们可以看到它正在工作。 Check it here

    【讨论】:

    • 在这种情况下,我不想用模块注册控制器(我注册它只是为了让它工作)。这种状态是唯一的用法,所以我宁愿直接指定它...
    • 我同时使用(typescript 和 UI-Router),并且会阻止您使用这种方法(您想要的方法)。试着用原生的角度方式来做。注册控制器,声明依赖(static $inject = [...]),让控制器过上它的生活。仅通过其字符串名称 (IoC) 将其加入状态。这样你就可以测试它 - 独立于状态......
    • 好的,已经足够好了,但我还是不明白为什么会有差异,这就是我发布问题的原因......
    • 我扩展了我的答案,并表明你的方法(我不会那样做)是有效的。我添加了工作 plunker 的链接并提供了更多详细信息。希望它可以帮助你一点...祝 TS 和 UI-Router 好运 ;)
    • 谢谢,我只是愚蠢地阅读文档,它清楚地说明了应该如何工作(正如你所强调的那样)......
    猜你喜欢
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    • 2016-04-11
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    相关资源
    最近更新 更多