如何创建AngularJS中我的方法可用的自定义对象类

时间:2014-11-11 13:24:05

标签: angularjs

我是角色的忠实粉丝,但它有一些棘手的概念,它们之间存在极其微妙的差异,这就是其中之一。

我只想创建一个可用于在Angular控制器和工厂中创建自定义对象的类。它肯定不应该那么难,但我无法弄清楚如何做到这一点。我想有一个自定义的ResultSet类,我可以实例化它来创建ResultSet的实例。然而,对于我的生活,我无法弄清楚工厂诉服务的正确语法。

这是所有我想要的:

ResultSet = function(dataSet){ 
  this.filter = function(){ 
    # filters and returns dataSet
    # ...
  }
}

然后我希望能够在控制器等中实例化ResultSet的实例:

MyApp.controller('pageCtrl', ['ResultSet',  (ResultSet) ->
  # ...
  rs = ResultSet.new(dataToFilter)

如何创建允许我创建自定义对象实例的服务?

使用Angular Service而不是Factory似乎更正确,因为服务返回一个对象的实例(这正是我想要的)。但我无法弄清楚如何做到这一点......

我如何使用服务声明我的自定义ResultSet类,然后如何从中实例化实例?

3 个答案:

答案 0 :(得分:13)

也许你正在寻找这样的东西:

function setClock() {
    $('.cont-s').empty(); // empty the circles div

    var totalSec =  sec--;
    var s = parseInt(totalSec % 60, 10);
    var result = s + " seconds to go!";

    document.getElementById('timeRemaining').innerHTML = result;

    if(totalSec === 0){
        document.getElementById('timeRemaining').innerHTML = 'time out';
    } else {
        for(var i = 0; i < s; i++){
            $('.cont-s').prepend('<div class="cir-s"></div>');
        }
        setTimeout(setClock, 1000);
    }
}

this帖子Gert Hengeveld

答案 1 :(得分:10)

myApp.factory('ResulSet', function() {
    function ResultSetInstance(dataSet) { 
        this.filter = function(){ 
            // ...
        }
    }

    return {
        createNew: function(dataSet) {
            return new ResultSetInstance(dataSet);
        }
    };
});

然后

myApp.controller('pageCtrl', function(ResultSet) {
    var someData = ...;
    var rs = ResultSet.createNew(someData);
}

编辑(来自提问者)

在进一步试验这一点后,我发现你甚至不需要createNew方法。

myApp.factory('ResultSetClass', function() {
    ResultSetClass = function(dataSet) { 
        this.filter = function(){ 
            // ...
        }
    }

    return ResultSetClass
});

工作得很好,然后你可以拨打new ResultSetClass(args)

使用Coffeescript

的注意事项

Coffeescript将返回类实例中的最后一个变量或方法,因此如果您使用coffeescript(作为一般规则),则必须在类定义的末尾返回this

myApp.factory 'ResultSetClass', () ->
  ResultSetClass = (dataset) ->
    this.filter = () ->
      # do some stuff
    return this

  return ResultSetClass

如果您没有明确地返回this,那么当您致电时,您会发现

myApp.factory 'ResultSetClass', () ->
  ResultSetClass = (dataset) ->
    this.filter = () ->
      # do some stuff

那么你只需要留下coffeescript返回的最后一个东西,即filter方法。

答案 2 :(得分:0)

最近我做了类似的事情,因为我想实现一个类实例的工厂,并且能够配置我的实例并从Angular Dependency注入中受益。我最终得到了这样的东西

// Implem
export class XAPIService {
  private path: string;
  /* this DO NOT use angular injection, this is done in the factory below */
  constructor(
    private seed: XAPISeed,
    private $http: ng.IHttpService,
    private slugService: SlugService
  ) {
    const PATH_MAP: Map<Y, Z> = new Map([
      ['x', id => `/x/${id}`],
      ['y', id => `/y/${id}`],
    ]);
    this.path = PATH_MAP.get(this.seed.type)(this.seed.id);
  }

  list() {
    /* implem that use configured path */
    return this.slugService
    .from(this.path + `/x`)
    .then(url => this.$http.get<IX>(url))
    .then(response => response.data)
  }
}

export type IXAPIFactory = (s: XAPISeed) => XAPIService;
export function XAPIFactory(
  $http: ng.IHttpService,
  myService: SlugService
) {
  'ngInject';
  return (seed: XAPISeed) =>
    new XAPIService(seed, $http, myService);
}

// angular 

angular.module('xxx', [])
  .factory('xAPIFactory', XAPIFactory)

// usage in code 

export class XsController implements ng.IComponentController {
  /* @ngInject */
  constructor(
    private xAPIFactory: IXAPIFactory,
  ) {}

  $onInit() {
    this.xService = this.xAPIFactory({ id: 'aaabbbaaabbb', type: 'y' });
    return this.xService.list()
      .then(xs => {
        this.xs = xs;
      })
  }  
}