您的位置:首页 > Web前端 > AngularJS

在AngularJS中使用ES6

2015-12-09 16:13 966 查看
本篇记录一些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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: