当前位置: 首页 > 面试题库 >

AngularJS-使用ES6导入而不是angular DI系统

慕承允
2023-03-14
问题内容

我将Webpack与angular 1.6.x和Typescript一起使用,而我退出使用angular
DI来支持ES6导入。当我需要ng之类的ng函数时$http$resourceangular.injector通过装饰器使用该函数直接注入它们,如下所示:

// inject.ts
    import * as angular from 'angular';

    export function inject (...params: string[]) {

        function doCall ( param: string, klass: Function) {
            const injector = angular.injector([ 'ng' ]);
            const service = injector.get(param);
            try {
                klass.prototype[ param ] = service;
            } catch ( e ) {
                window.console.warn( e );
            }
        }

        // tslint:disable-next-line:ban-types
        return function ( klass: Function ) {
            params.forEach( ( param ) => {
                doCall( param, klass );
            } );
        };
    }

// posts.service.ts
import { inject } from './inject';
import { IPost, Post } from './post';

@inject('$http')
export class PostsService {
    public $http: angular.IHttpService;
    get (): Promise<IPost[]> {
        const posts: IPost[] = [];
        const promise = new Promise<IPost[]>( (resolve, reject) => {
            this.$http.get<IPost[]>('https://jsonplaceholder.typicode.com/posts')
            .then(( response ) => {
                response.data.forEach(item => {
                    posts.push( new Post(item) );
                });

                resolve( posts );
            });
        });

        return promise;
    }
}


// post.ts
export interface IPost {
    userId: number;
    id: number;
    title: string;
    body: string;
}
export class Post implements IPost {
    userId: number;
    id: number;
    title: string;
    body: string;

    constructor (item: IPost) {
        this.userId = item.userId;
        this.id = item.id;
        this.title = item.title;
        this.body = item.body;
    }
}


// controller.ts
import { IPost } from './post';
import { PostsService } from './posts.service';

export class Controller {
    public postService: PostsService;
    public posts: IPost[];
    constructor ( private $scope: angular.IScope ) {
        this.postService = new PostsService();
    }

    $onInit () {
        this.postService.get()
        .then((posts) => {
            this.posts = posts;
            this.$scope.$digest();
        });
    }
}

// index.ts
import * as angular from 'angular';

import { Controller } from './app/controller';

import './index.scss';

export const app: string = 'app';

angular
  .module(app, [])
  .controller('controller', Controller);


angular.bootstrap(document.body, [app]);

我不知道它是否符合最佳实践,但到目前为止,它的运行情况还不错。

我想听听您对这个问题的想法:使用这种方法是否存在任何问题(性能,不良做法等)?


问题答案:

ES模块不能替代Angular模块和DI。它们相互补充,并保持应用程序模块化和可测试。

ES6模块提供了额外的可扩展性层,例如控制器/服务子类化(单独使用Angular模块和DI看起来不太好)。

ES6或TypeScript的推荐方法是按常规方式进行DI,并带有$inject注释:

export class PostsService {
  static $inject = ['$http'];
  constructor(
    public $http: angular.IHttpService
  ) {}
  ...
}

每个文件只有一个模块也是一种好习惯,这样应用程序可以保持模块化和可测试性:

export default angular.module('app.posts', [])
  .service('posts', `PostsService)
  .name;`

它的default导出是可以在直接依赖于它的另一个模块中导入的模块名称:

import postsModule from '...';
...
export default angular.module('app.controller', [postsModule])
  .controller('controller', Controller)
  .name;`

装饰器通常无法到达应用程序注射器。即使黑客有可能使其在生产环境中正常工作,它也会在测试中陷入混乱。

angular.injector 创建新的注入器(即应用程序实例),并且在生产中的使用用途非常有限:

angular.injector(['ng']).get('$rootScope') !== angular.injector(['ng']).get('$rootScope');

当开发人员不知道如何获取当前$injector实例时,通常会滥用它。当然不应该在这种情况下使用它。



 类似资料:
  • 问题内容: 通过使用,我可以在 文件名 内包含并执行代码,而无需在 文件名 内定义任何导出。 ES6中使用的等效项是什么? 谢谢 问题答案: 等效的就是: 以下是一些可能的语法变体: 消息来源: MDN

  • 问题内容: 在我正在合作的项目中,关于可以使用哪种模块系统,我们有两个选择: 导入使用的模块,并使用导出和。 使用ES6导入模块,并使用ES6导出 相互使用是否对性能有好处?如果要在Node模块上使用ES6模块,还有其他什么应该知道的吗? 问题答案: 相互使用是否对性能有好处? 请记住,还没有JavaScript引擎本身支持ES6模块。您说自己正在使用Babel。无论如何,Babel都会默认将其转

  • 指定:这就是表的样子。 希望得到的结果是由Hibernate为我构建的SQL查询:

  • 如果我使用ES6中的,那么我的所有Jest测试都会失败,并出现错误: 意外保留字 我将测试对象转换为使用老式IIFE语法,突然我的测试通过了。或者,以更简单的测试用例为例: 同样的错误。显然这里的导入/导出有问题。对我来说,仅仅为了让我的测试框架开心而使用ES5语法重写代码是不现实的。 我有巴别塔笑话。我尝试了GitHub问题的各种建议。这是不可能的。 有解决办法吗?

  • 有没有办法在没有导入语句的情况下使用标准库类扫描仪? 除了反编译标准库和添加所有的函数之外,我的教授是一种包括那些不希望你真正完成的非常困难的问题的人。java文件到这个项目我有点不知所措。 编辑:为了澄清,这是实验室描述的确切措辞:“使用扫描仪从用户那里获取整数值。

  • 问题内容: 但是我仍然不知道您何时在工厂使用服务。 据我所知,工厂通常用于创建可被多个控制器调用的“通用”功能:创建通用控制器功能 Angular文档似乎更喜欢工厂而不是服务。他们甚至在使用工厂时也提到“服务”,这更加令人困惑!http://docs.angularjs.org/guide/dev_guide.services.creating_services 那么什么时候可以使用服务呢? 有什