如何在TypeScript中使用AngularJS的app.service和$q?

4

我对TypeScript和AngularJS非常陌生。我无法找到正确的答案,以下是我的代码:

export class SidenavController {
static $inject = ['$scope', '$mdSidenav'];
     constructor(private $scope: any,private $mdSidenav: any) {

     }
toggleSidenav(name: string) {
    this.$mdSidenav(name).toggle();
     }
  loadHelpInfo() {
    this.helpService.loadAll()
      .then(function(help) {
        this.$scope.helpInfo = [].concat(help);
        this.$scope.selected = this.$scope.helpInfo[0];
      })
  }
  selectHelpInfo(help) {
    this.$scope.selected = angular.isNumber(help) ? this.$scope.helpInfo[help] : help;
    this.$scope.toggleSidenav('left');
  } 

}
app.service('helpService', ['$q', function($q) {
  var helpInfo = [{
      name: 'Introduction',
      content: '1 '
  }, {
      name: 'Glossary',
      content: '2'
  }, {
      name: 'Log In',
      content: '3'
      }, {
      name: 'Home Page',
      content: '4'
  }];

  return {
      loadAll: function() {
          return $q.when(helpInfo);
      }
  };
}]);

在上述代码中,我希望使用helpService加载屏幕上的详细信息。 执行时出现以下错误: app/components/sidenav/sidenav-controller.ts(10,10): error TS2339: Property 'helpService' does not exist on type 'SidenavController'。 我不确定如何在TypeScript中使用服务。 如果需要,我已经做了Angular的CodePen版本。

http://codepen.io/snehav27/pen/JdNvBV

基本上我正在尝试将上面的片段转换成TypeScript版本。

你需要注入helpservice。 - PSL
1个回答

1
你需要注入helpservice并将其设置为构造函数参数。
     static $inject = ['$scope', '$mdSidenav', 'helpService'];
     constructor(private $scope: any,private $mdSidenav: any, private helpService:any) {

     }

否则,TypeScript 将不知道您所指的是什么 this.helpService,即使没有 TS,当您尝试使用 this.helpService.loadAll 时,也会导致错误,如 "cannot access loadAll of undefined" 或类似的错误。

此外,请使用箭头操作符来解析词法作用域的 this @

  this.helpService.loadAll()
  .then((help) => { //<-- here
    this.$scope.helpInfo = [].concat(help);
    this.$scope.selected = this.$scope.helpInfo[0];
  });

否则,由于回调函数内的this不会是控制器实例,会导致另一个错误。
您还可以为helpService创建一个类型,以便更好地使用并减少任何拼写错误。
export interface IHelpService{
  loadAll():ng.IPromise<Array<HelpInfo>>; //use specific typing instead of any
}

export interface HelpInfo{
  name:string;
  content:string;
}

class HelpService implements IHelpService{
    private _helpInfo:Array<HelpInfo> = [{
      name: 'Introduction',
      content: '1 '
  }, {
      name: 'Glossary',
      content: '2'
  }, {
      name: 'Log In',
      content: '3'
      }, {
      name: 'Home Page',
      content: '4'
   }];

    static $inject = ['$q'];
    constructor(private $q:ng.IQService){
    }

    loadAll(){
       return this.$q.when(this._helpInfo);
    }

 }

angular.module('HelpApp').service('helpService', HelpService);

并且

 constructor(private $scope: any,private $mdSidenav: any, private helpService:IHelpService) {

最好使用“controller as”语法与Typescript类定义一起使用,完全摆脱将属性附加到作用域上的方式。目前的情况是半成品(函数附加到控制器实例和一些属性附加到作用域上)。

export class SidenavController {

    helpInfo:Array<HelpInfo>;
    selected:HelpInfo; 

    static $inject = ['$mdSidenav', 'helpService'];
    constructor(private $mdSidenav: any, private helpService:IHelpService) {}

     toggleSidenav(name: string) {
        this.$mdSidenav(name).toggle();
     }

     loadHelpInfo() {
        this.helpService.loadAll()
          .then((help) => {
            this.helpInfo = [].concat(help);
            this.selected = this.helpInfo[0];
          })
      }

      selectHelpInfo(help) {
        this.selected = angular.isNumber(help) ? this.helpInfo[help] : help;
        this.toggleSidenav('left');
      } 

}

而在您的看法中:

<body layout="column" ng-controller="AppCtrl as vm">

请参考以vm为前缀的属性和方法(你可以使用任何别名,我只是使用了vm)。例如(其余部分应该很容易理解):

<md-item ng-repeat="it in vm.helpInfo">

<--- some code -->

 <md-button ng-click="vm.selectHelpInfo(it)" 
            ng-class="{'selected' : it === vm.selected }">

1
最好使用控制器作为语法并摆脱作用域。我不确定在你原来的代码片段中如何将它们绑定到视图,因为方法附加到控制器实例上,而某些属性则附加到作用域上。 - PSL
如果您包含了mdSideNav typings,那么您也可以这样做:constructor(private $mdSidenav: angular.material.MDSidenavObject, - PSL
我遇到了这个错误:TS4057:从导出接口的方法的返回类型使用了私有名称'ng'。它指向:loadAll():ng.IPromise <Array <HelpInfo>>; - user2936008
http://codepen.io/snehav27/pen/JdNvBV - 当我切换到TypeScript时,出现了一些问题。 - user2936008
但是当我尝试从本地运行时,我遇到了上面提到的错误。 - user2936008
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/80115/discussion-between-psl-and-user2936008。 - PSL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接