简体   繁体   English

PhpStorm/WebStorm:AngularJS 注入的服务/工厂是否有任何类型的代码完成

[英]PhpStorm/WebStorm: Is there any kind of code-completion for AngularJS injected services/factories

I like WebStorm autocompletion, and use types (jsdoc or .d.ts) everywhere I can.我喜欢 WebStorm 自动补全,并尽可能使用类型(jsdoc 或 .d.ts)。

By using Angular, I wanted to get code-autocompletion of injected service.通过使用 Angular,我想获得注入服务的代码自动完成功能。 But did not find anything about this.但没有发现任何关于此的信息。

Is there any workaround or right solution to get autocompletion eg in such code:是否有任何解决方法或正确的解决方案来获得自动完成,例如在这样的代码中:

//SERVICE file
angular
  .module('testModule')
  .service('someService', someService);

function someService() {
  return {
    method1: method1,
  };

  /**
   * here some description
   */
  function method1() {
  }
}

//CONTROLLER file
angular
  .module('testModule')
  .controller('testCtrl', testCtrl);

testCtrl.$inject = ['someService'];

function testCtrl(someService) {
  //here i want to have autocompletion of all possible methods of the 'someService' service
  someService.method1();
}

Edit: possible solutions i found for now编辑:我现在找到的可能的解决方案

the first one ist just use JSDOC.第一个就是使用 JSDOC。 eg例如

//SERVICE file
angular
  .module('testModule')
  .service('someService', someService);


/**
 * some nice service
 */
function someService() {
  /**
   * here some description
   */
  this.method1 = function() {
  }
}



//FACTORY file example
/**
 * for factory, you should define and instantiate the class,
 * or write big jsdoc with @typedef //bad way
 * @returns {someService}
 */
function someFactory() {
  //return new someService(); //easy way, since all methods are described in the class

  //hard way, since you have to define all methods and return types in @typedef again

  /**
   * @typedef {{method1OfFactory: function()}} someService
   */
  var retObj = {}
  retObj.method1OfFactory = function(){}
  return retObj;
}



//CONTROLLER file
angular
  .module('testModule')
  .controller('testCtrl', testCtrl);

testCtrl.$inject = ['someService'];

/**
 * one of solution, just jsdoc
 * @param {someService} someService
 */
function testCtrl(someService) {
  someService.method1(); //here you got the autocompletion
}

//alternative inline type doc
function testCtrl2(/**someService*/someService) {
  someService.method1(); //here you got the autocompletion
}

//alternative fake declaration declaration (see menya's answer)
function testCtrl3(someService) {
  false ? someService = new someService() : '';
  someService.method1(); //here you got the autocompletion
}

Edit2: best solution i use for now (will be 'answer' after some time): Edit2:我现在使用的最佳解决方案(一段时间后将是“答案”):

////FILE: some.factory.js
(function factoryIIFE() { //IIFE
  'use strict';

  angular
    .module('module1')
    .factory('someByFactory', SomeFactory);

  function SomeFactory() {
    /**@class module1.SomeByFactory*/
    return {
      someFactoryMethod: someFactoryMethod
    };

    /**
     * @return {string} by factory method
     */
    function someFactoryMethod() {
      return 'someFactoryMethod';
    }
  }

}()); //IIFE

////FILE: some.service.js
(function someServiceIIFE() { //IIFE
  'use strict';

  angular
    .module('module1')
    .service('someService', SomeService);

  SomeService.$inject = ['someByFactory'];
  /**
   * info: the name of service/factory should NOT match function name
   * so use namespace, like in the example, or rename function
   * i think its because of IIFE
   * @param {module1.SomeByFactory} createdByFactory
   * @class module1.SomeService
   * @constructor
   */
  function SomeService(createdByFactory) {
    /**
     * @return {string} text, using factory
     */
    this.someServiceMethod = function(){
      return 'service method, calling;' + createdByFactory.someFactoryMethod();
    }
  }

}()); //IIFE

////FILE: some.directive.js
(function directiveIIFE() { //IIFE
  'use strict';

  angular
    .module('module1')
    .directive('someDirective', directive);

  function directive() {
    return {
      templateUrl     : 'directive.html',
      restrict        : 'E',
      link            : link,
      controller      : DirectiveCtrl,
      controllerAs    : 'vm',
      bindToController: true,
    };
  }

  function link(scope, element, attrs, /**DirectiveCtrl*/ctrl) {
    scope.text = ctrl.anyProp;
    scope.textFactory = ctrl.serviceResult;
    scope.textService = ctrl.factoryResult;
  }

  DirectiveCtrl.$inject = ['someService', 'someByFactory'];

  /**
   *
   * @param {module1.SomeService} someService
   * @param {module1.SomeByFactory} fromFactory
   * @constructor
   */
  function DirectiveCtrl(someService, fromFactory) {
    var vm = this;
    vm.anyProp = 'ctrl prop';
    vm.serviceResult = someService.someServiceMethod();
    vm.factoryResult = fromFactory.someFactoryMethod();
  }

}()); //IIFE

Workaround is to create new object of someService.解决方法是创建 someService 的新对象。

function testCtrl(someService) {
  var srv = new someService();
  srv.             // now autocompletion will work
}

But all services is a singletons, so that code will cause an error.但是所有的服务都是单例的,所以这样的代码会导致错误。 We can do the trick like this:我们可以这样做:

function testCtrl(someService) {      

  false ? this._srv = new someService() : '';
  this._srv = someService;

  this._srv.             // now autocompletion will work
}

Webstorm now will aoutocomplete and then we run code service will not initialize so we dont brake our code; Webstorm 现在会自动完成,然后我们运行的代码服务不会初始化,所以我们不会刹车我们的代码;

It's not perfect solution, but it's all i wound.这不是完美的解决方案,但这就是我的全部。 If you find better solution, please, let me know.如果您找到更好的解决方案,请告诉我。

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

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