使用Angularjs和Typescript进行服务

时间:2016-01-08 08:38:03

标签: angularjs typescript

我有一个读取json文件的$ http服务。我想使用模块化,但我不知道如何在我的控制器中调用我的服务,我不知道我的服务是否写得很好。

这里有一个jsFidlle:https://jsfiddle.net/aqbmdrvn/

感谢!!!

/// <reference path="../../typings/angularjs/angular.d.ts" />
/// <reference path="../../typings/angularjs/angular-route.d.ts" />
/// <reference path="../app.ts" />  
/// <reference path="servicePets.ts" />
"use strict";

module AnimalPlanet {
    // pet interface
    export interface IPet {
        type: string;
        name: string;
        age: number;
        color: string;
        specialCare: boolean;
        availableForAdoption: boolean;
        ldAdoption: boolean;
        history: string;
        featured: boolean;
        newest: boolean;
        imageUrl: string;
    }

    export interface RootObject {
        pets: IPet[];
    }
    // pet controller with ui-grid
    export class petsCtrl implements RootObject {
        pets: IPet[];
        constructor(private $http: ng.IHttpService,public petsService,  private $scope: any, uiGridConstants: any, filterldAdoption: any) {
            $scope.pets = {};
            // ui grid option
            $scope.gridOptions = {
                enableSorting: true,
                enableFiltering: true,
                paginationPageSizes: [5, 10, 15],
                paginationPageSize: 5,
                onRegisterApi: (gridApi) => {
                    $scope.gridApi = gridApi;
                },
                columnDefs: [
                    {
                        name: 'type',
                        cellTooltip: true,
                        headerTooltip: true
                    },
                    {
                        name: 'name',
                        cellTooltip: true,
                        headerTooltip: true
                    },

                    {
                        name: 'age',
                        // filters: [{
                        //     condition: uiGridConstants.filter.GREATER_THAN,
                        //     placeholder: 'greater than'
                        // }, {
                        //         condition: uiGridConstants.filter.LESS_THAN,
                        //         placeholder: 'less than'
                        //     }
                        // ],
                        cellTooltip: true,
                        headerTooltip: true
                    },
                    {
                        name: 'color',
                        cellTooltip: true,
                        headerTooltip: true

                    },
                    {
                        name: 'specialCare',
                        cellTooltip: true,
                        headerTooltip: true
                    },
                    {
                        name: 'availableForAdoption',
                        cellTooltip: true,
                        headerTooltip: true
                    },
                    {
                        name: 'history',
                        cellTooltip: true,
                        headerTooltip: true
                    },
                    {
                        name: 'featured',
                        cellTooltip: true,
                        headerTooltip: true
                    },
                    {
                        name: 'newest',
                        cellTooltip: true,
                        headerTooltip: true
                    },
                    {
                        name: 'imageUrl',
                        cellTooltip: true,
                        headerTooltip: true,
                        enableFiltering: false,
                        enableHiding: false,
                        cellTemplate: "<img width=\"50px\" ng-src=\"{{grid.getCellValue(row, col)}}\" lazy-src>"
                    }
                ]
            };
            // read json using http service
            this.$http.get('/app/pets/pets.json').success((data) => { // pune te rog asta intr-un serviciu

                // fill ui grid using http service
                $scope.filterPets = data;
                var uiGridPets = [];
                angular.forEach($scope.filterPets, (item) => {
                    if (item.ldAdoption) {
                        uiGridPets.push(item);
                    }
                });

                $scope.gridOptions.data = uiGridPets;

                // filter for main page with 3 pets
                $scope.pets = data;
                $scope.quantity = 3;
                var featuredPets = [];
                var newestPets =[];
                angular.forEach($scope.pets, (item) => {
                    if (item.featured) {

                        featuredPets.push(item);

                    }
                    if(item.newest){
                        newestPets.push(item);
                    }

                });
                $scope.featuredPets = featuredPets;
                $scope.newestPets = newestPets;
           });
            $scope.fromService = petsService.weatherChange();
        }

    }

    petsCtrl.$inject = ['$http', '$scope', 'uiGridConstants', 'petsService'];
    app.controller("petsCtrl", petsCtrl);


}
/// <reference path="../../typings/angularjs/angular.d.ts" />
/// <reference path="../../typings/angularjs/angular-route.d.ts" />
/// <reference path="../app.ts" />  

"use strict";

module AnimalPlanet {
    export interface IPetsService {
        http: ng.IHttpService;
        uiGridConstants: any;
    }
    export class servicePets implements IPetsService {
       http: ng.IHttpService;
       uiGridConstants: any;
        constructor( $scope:any , $http: ng.IHttpService, uiGridConstants: any )
        {
             // read json using http service
            $scope.pets = {};
            this.http = $http;
        }
        public get() {
            this.http.get('/app/pets/pets.json').success((data) => { // pune te rog asta intr-un serviciu

                // fill ui grid using http service
                var filterPets = data;
                var uiGridPets = [];
                angular.forEach(filterPets, (item) => {
                    if (item.ldAdoption) {
                        uiGridPets.push(item);
                    }
                });

                var gridOptions.data = uiGridPets;

                // filter for main page with 3 pets
                var pets = data;

                var quantity = 3;
                var featuredPets = [];
                var newestPets =[];
                angular.forEach(pets, (item) => {
                    if (item.featured) {

                        featuredPets.push(item);

                    }
                    if(item.newest){
                        newestPets.push(item);
                    }

                });
                var featuredPets = featuredPets;
                var newestPets = newestPets;
            });
    }

    }

    servicePets.$inject = ['$http', '$scope', 'uiGridConstants'];
    app.service('servicePets', servicePets);

}

2 个答案:

答案 0 :(得分:2)

这是我用于样板控制器和工厂的内容:

控制器代码:

declare var app: angular.IModule;

class MyController {
    static $inject = ['myService'];

    localData: IGetDataResult;

    constructor(private myService: MyService) {
        this.myService.getData('key1')
            .then(result => {
                this.localData = result.data;
            });
    }
}

app.controller('myController', MyController);

工厂代码:

declare var app: angular.IModule;

interface IGetDataResult {
    field1: string;
}

class MyService {
    static $inject = ['$http'];

    constructor(private $http: angular.IHttpService) {
    }

    getData(key: string): angular.IHttpPromise<IGetDataResult> {
        return this.$http({
            method: 'POST',
            data: {
                key: key
            },
            url: '/WebService/GetData'
        });
    }
}

function MyServiceFactory($rootElement) : MyService {
    const inj = $rootElement.injector();
    return inj.instantiate(MyService);
}
app.factory('myService', ['$rootElement', $rootElement => MyServiceFactory($rootElement)]);

一些解释:

  • 控制器很简单,但请注意静态注入变量$inject的用法。该数组中元素的顺序必须与构造函数中的参数顺序相对应。
  • 我的工厂由工厂功能实例化(原谅双关语)。请注意,我正在$rootElement注入依赖项。我发现如果我想使用$location,我必须使用$rootElement上实例化的注入器。
  • 我在$http电话上使用了强类型的返回值。这显然有很多原因。
  • 请注意,除$rootElement外,所有内容都是明确输入的。 angular.d.ts中包含injector()函数的
  • 没有匹配类型。

还有一件事,打字稿适用于controllerAs方法。这意味着您不需要将$scope注入控制器,并且在您的html中,您必须在每个范围表达式之前添加控制器别名(controllerAs值)。当这样做时,您将所有范围变量和函数作为成员放在控制器上。

如果你想使用$scope$watch,有时你需要注入$on,但是有一些问题,关于this关闭,但是这是另一篇文章的主题。

ui-grid的一个问题是,如果您为gridoptions.data成员使用字符串值,则它还必须包含控制器别名前缀。

答案 1 :(得分:0)

要模块化您的代码,您希望将$ http调用及其依赖注入重构出控制器并进入服务。

将服务注入控制器时,需要考虑模块“命名空间”。所以,你的$ inject看起来像:“AnimalPlanet.petsService”。这可能是您在从控制器调用服务时遇到问题的原因。看起来它没有正确接线。

我不会以你的方式使用$ inject。我遵循这种模式:

// Dependencies for this controller.
static $inject = ["$q",
    "$location",
    "$window",
    "$scope",
    "$log",
    "common",
    "RL.SS.Portal.RLToday.Services.AroundTheIndustryService",
    "RL.SS.Portal.RLToday.Services.LocationFilterService"];

这就是类定义本身。我不知道这是否一定更准确,但您可能会发现它很有用。

在控制器的构造函数中,你不需要(也可能不应该)将petservice引用公开,但这不是你的问题,只是一种风格的东西。

一旦你注射正确,你就可以通过你的控制器来做到这一点:

this.petsService.Get().then( () => { /* success */ }, () => { /* fail */});

HTH。

(这是我第一次尝试回答堆栈溢出问题,所以如果有人想告诉我如何做得更好,请随意这样做。)