在AngularJS中使用ES6

本篇记录一些AngularJS结合使用ES6的各种写法。

ES6中module的导出导入

class MainController {
    constructor(searchService){
        this.searchService = searchService;
    }

    search(){
        this.searchService
            .fetch(this.searchTerm)
            .then(response => {
                this.items = resposne.data.items;
            })
    }
}

export {MainController}

如何把module中的Controller注册进module呢?

import {MainController } from ‘./MainController‘;
import {searchService } from ‘./SeachService‘;

angualr
    .module(‘app‘,[])
    .controller(‘mainController‘, MainController)
    .service(‘searchService‘, searchService);

ES6中的继承

class PageController{
    constructor(name){
        this.name = name;
    }

    sayHello(){
        return ‘Hello ‘ + this.name;
    }
}

export {PageController}

在另外一个文件中:

import {PageController} from ‘./PageController‘;

class ProductPageController extends PageController {
    constructor(){
        super(‘jack‘);
    }
}

export {ProductPageController}

最后注册到module中去:

angular
    .module(‘app‘,[])
    .controller(‘ProductPageController‘, ProductPageController);

ES6中Service和Controller的写法

class UserService{
    constructor($http){
        this.$http = $http;
    }

    getFullName(){
        return this.$http.get(‘api/user/details‘);
    }
}

class MyController{
    //注意:定义时的class名是UserService,正真的名称是在service(‘realname‘,UserServie)中定义的
    constructor(userService){
        userService.getFullName().then(result => this.userName = result.fullName);
    }
}

angular.module(‘app‘)
    .service(‘userService‘, UserService)
    .controller(‘MyController‘, MyController);

ES6中Providers的写法

class MyProvider{
    constructor(){
        this.apiPath = ‘default/api‘;
    }
    setApiPath(value){
        this.apiPath = value;
    }
    $get($http){
        return {
            getThings: () => $http.get(this.apiPath);
        }
    }
}

ES6的Provider中依赖的注入是写在$get()中的,不能在constructor中注入。Provider中必须有$get()方法。

ES6中Factory的写法

class Thing{
    constructor(){
        console.log(‘create the thing‘);
        showMsg();
    }
    showMsg(){
        console.log(‘some msg‘);
    }
}

class ThingFactory{
    constructor($timeout){
        this.$timeout = $timeout;
    }

    createThing(){
        return this.$timeout(() => new Thing(),1000);
    }
}

如何往module中注册呢?

● 第一种写法

angular.module(‘app‘)
    .factory(‘thingFactory‘, () => new ThingFactory());

以上写法是错误的,因为$timeout还没有注入进去。可以这样写。

angular.module(‘app‘)
    .factory(‘thingFactory‘, [‘$timeout‘, ($timeout) => new ThingFactory($timeout)]);

● 第二种写法

但,以上的写法也不是最理想的。最好是写在类中。

class ThingFactory{
    constructor($timeout){
        this.$timeout = $timeout;
    }

    createThing(){
        return this.$timeout(() => new Thing(),1000);
    }
}

ThingFactory.$inject = [‘$timeout‘];

然后,

angular.module(‘app‘)
    .factory(‘thingFactory‘, () => new ThingFactory());

● 第三种写法

class ThingFactory{
    constructor($timeout){
        this.$timeout = $timeout;
    }

    createThing(){
        return this.$timeout(() => new Thing(),1000);
    }
}

ThingFactory.$inject = [‘$timeout‘];

var constructorFn = ThingFactory;

//args = [‘$timeout‘]
var args = constructorFn.$inject;

//根据参数创建ThingFactory实例,任意多的参数
var factoryFunction = (...args) => {
    return new constructorFn(...args);
}

//[‘$timeout‘, ($timeout) => new ThingFactory($timeout)]
var factoryArray = args.push(factoryFunction);

angular.module(‘app‘)
    .factory(‘thingFactory‘, factoryArray);

ES6中Directive的写法

class MyDirective{
    constructor($interval){
        this.template = ‘<div>I\‘m a directive</div>‘;
        this.restrict = ‘E‘;
        this.scope = {};
        this.$interval = $interval;
    }

    compile(tElement){
        tElement.css(‘position‘,‘absolute‘);
    }

    link(scope, element){
        this.$interval(() => this.move(element),1000);
    }

    move(element){
        element.css(‘left‘, (Math.random() * 500) + ‘px‘);
        element.css(‘top‘, (Math.random() * 500) + ‘px‘);
    }
}

以上,如果同时使用compile和link方法,link方法应该是compile的返回值。

compile(tElement){
    tElement.css(‘position‘,‘absolute‘);
    return this.link;
}

以上,当angular调用this.link方法,将不会在MyDirective的当前上下文中,调用this.$interval(() => this.move(element),1000);会报undefined类型错误。

如果改成这样:

compile(tElement){
    tElement.css(‘position‘,‘absolute‘);
    return (scope, element) => {
        this.$interval(() => this.move(element),1000);
    };
}

这里,当使用=>后,调用this.$interval(() => this.move(element),1000);方法能保证还MyDirective所在的当前上下文中。

还可以这么写:

compile(tElement){
    tElement.css(‘position‘,‘absolute‘);
    return this.link.bind(this);
}

link(scope, element){
    this.$interval(() => this.move(element),1000);
}

但, 以上所有的做法都必须调用compile方法,而在实际场景中,调用compile方法不是必须的。最好这样写:

var constructorFn = MyDirective;

//是否有compile方法
if (!constructorFn.prototype.compile) {
    // 如果没有,通过原型创建compile方法
    constructorFn.prototype.compile = () => {};
}

var originalCompileFn = _cloneFunction(constructorFn.prototype.compile);

//重写compile方法
_override(constructorFn.prototype, ‘compile‘, function () {
    return function () {

        //先调用原先的compile方法
        originalCompileFn.apply(this, arguments);

        //如果Directive包含link方法再执行link方法,绑定正确的上下文
        if (constructorFn.prototype.link) {
            return constructorFn.prototype.link.bind(this);
        }
    };
});

往module注册controller、factory、provider等的帮助方法

Michael Bromley还专门写了一个帮助方法,在这里

大致这样使用:

class MyAngularComponent {
    /*@ngInject*/
    constructor(dependency1, dependency2) {
        this.dependency1 = dependency1;
        // stuff happens here
    }
    someMethods() {
        this.dependency1.doThatThing();
        // more stuff here
    }
}

register(‘app‘)
    .controller(‘MyController‘, MyAngularComponent)
    .service(‘myService‘, MyAngularComponent)
    .provider(‘myOtherService‘, MyAngularComponent)
    .factory(‘myFactory‘, MyAngularComponent)
    .directive(‘myDirective‘, MyAngularComponent);

参考资料:
http://blog.thoughtram.io/angularjs/es6/2015/01/23/exploring-angular-1.3-using-es6.html
http://www.michaelbromley.co.uk/blog/350/exploring-es6-classes-in-angularjs-1-x
https://github.com/timroes/angular-es6-sample

时间: 2024-10-13 00:56:24

在AngularJS中使用ES6的相关文章

angularJS中XHR与promise

angularJS应用是完全运行在客户端的应用,我们可以通过angularJS构建一个不需依赖于后端,同时能够实现动态内容和响应的web应用,angularJS提供了将应用与远程服务器的信息集成在一起的方法 $http服务 angularJS提供了内置的$http服务直接同外部进行通信,$http服务封装了浏览器原生的XMLHttpRequest对象 $http服务只接收一个参数对象,包含了用来生成http请求的配置内容,$http函数返回一个promise对象,具有success和error两

Angularjs中的promise

promise 是一种用异步方式处理值的方法,promise是对象,代表了一个函数最终可能的返回值或抛出的异常.在与远程对象打交道非常有用,可以把它们看成一个远程对象的代理. 要在Angular中创建promise需要使用内置的$q服务.先用factory定义一个服务,注入$q服务. angular.module('readApp').factory('asyncService', [ "$q", function ($q) { var myAsync=function(flag) {

angularJs中关于ng-class的三种使用方式说明

在开发中我们通常会遇到一种需求:一个元素在不同的状态需要展现不同的样子. 而在这所谓的样子当然就是改变其css的属性,而实现能动态的改变其属性值,必然只能是更换其class属性 这里有三种方法: 第一种:通过数据的双向绑定(不推荐) 第二种:通过对象数组 第三种:通过key/value 下面简单说下这三种: 第一种:通过数据的双向绑定 实现方式: function changeClass(){   $scope.className = "change2"; } <div clas

AngularJs中的directives(指令)

一.指令的职责   指令的职责是修改DOM结构,并将作用域和DOM连接起来.即指令既要操作DOM,将作用域内的数据绑定到DOM节点上,又要为DOM绑定事件调用作用域内的对应的方法. 二.创建自定义指令 调用自定义指令的4种方式:元素.属性.样式类.注释. 常用的是前两种,实例如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title>

黄聪:AngularJS中的$resource使用与Restful资源交互(转)

原文:http://blog.csdn.net/he90227/article/details/50525836 1.AngularJS中的 $resource 这个服务可以创建一个资源对象,我们可以用它非常方便地同支持RESTful的服务端数据源进行交互,当同支持RESTful的数据模型一起工作时,它就派上用场了.      REST是Representational State Transfer(表征状态转移)的缩写,是服务器用来智能化地提供数据服务的一种方式 1)我们首先需要引入ng-Re

Spring Boot+AngularJS中因为跨域导致Session丢失

http://blog.csdn.net/dalangzhonghangxing/article/details/52446821 如果还在为跨域问题烦恼,请查看博主的 解决angular+spring boot的跨域问题 那篇文章. 博主在项目开发过程中,遇到了由于跨域而导致的Session丢失问题,非常的恶心,但是经过在网上查阅各种资料,发现解决方法十分简单. 在我们每一次的数据请求中,浏览器都会向后台发送一个JSession,后台会根据这个值自动查找Id为JSession的那个sessio

后端接收不到AngularJs中$http.post发送的数据的问题

1.问题: 后端接收不到AngularJs中$http.post发送的数据,总是显示为null 示例代码: $http.post(/admin/KeyValue/GetListByPage, { pageindex: 1, pagesize: 8 }) .success(function(){ alert("Mr靖"); }); 代码没有错,但是在后台却接收不到数据,这是为什么呢? 用火狐监控:参数是JSON格式 用谷歌监控:传参方式是request payload 可以发现传参方式是

Angularjs中的事件广播-浅谈$broadcast,$emit,$on

Angularjs中不同作用域之间可以通过组合使用$broadcast,$emit,$on的事件广播机制来进行通信 介绍: $broadcast的作用是将事件从父级作用域传播至子级作用域,包括自己.格式如下:$broadcast(eventName,args) $emit的作用是将事件从子级作用域传播至父级作用域,包括自己,直至根作用域.格式如下:$emit(eventName,args) $on用于在作用域中监控从子级或父级作用域中传播的事件以及相应的数据.格式如下:$on(event,dat

AngularJs中,如何在父元素中调用子元素为自定义Directive中定义的函数?

最近一段时间准备使用AngularJs中的自定义Directive重构一下代码. 在这里说明一下,把自定义控件封装成Directive并不一定是要复用,而是要让代码结构更加清晰.就好像你将一个长方法拆分成多个独立的小方法,也未必要复用它们一样.职责独立等一票好处,会让后期维护更加轻松. 在重构的过程中,我遇到了这样一个问题,先上图: 图一: 这就是我要重构的界面,由于之前时间紧,将这三个Filter和两个button都写在了一个页面中.当时我已经预感到,如果将这里面的状态都写到一个scope上,