2015-09-03 2 views
6

Я пытаюсь использовать класс ES6 как услугу с угловым выражением, но при его создании методы не имеют доступа к переменным-конструкторам.Угловое обслуживание с классом ES6 и Babel

class dataWrapperService { 

    constructor($q, $log) { 
     this.$q = $q; 
     this.$log = $log; 
    } 

    data() { 
     console.log(this.$q); 
    } 
} 

dataWrapperService.$inject = ['$q', '$log']; 

app.service('dataWrapper', dataWrapperService); 

После того, как услуга получает впрыскивается Угловым и я вызываю метод передачи данных по нему, методу не может иметь доступ к значениям конструкторы.

// calling the data method results in an error 
dataWrapper.data(); //TypeError: Cannot read property '$q' of undefined 

// console.log output of dataWrapper: 
Object 
    $log: Object 
    $q: Q(resolver) 
    __proto__: smDataWrapperService 
    constructor: smDataWrapperService($q, $log) 
    data: data() 
    __proto__: Object 

НО ...

я могу новый dataWrapperService вручную и что работает просто отлично.

var dataWrapper = new smDataWrapperService("hello", "sir"); 
dataWrapper.data(); // "hello" 

Что мне здесь не хватает?

UPDATE:


Это, кажется, происходит только в обещание обратных вызовов:

Я обычно проходят функции затем/уловом как это:

$http.get('whatever').then(dataWrapper.data); 

Но только следующие будут работать:

$http.get('whatever').then((response) => smDataWrapper.data(response)) 

ответ

3

Угловая потребность в функции на app.factory('dataWrapper', dataWrapperService); и не в классе.

Вы можете добавить статический заводский метод в свой класс и добавить его в app.factory. (см обновление ниже фрагмент кода)

код, как это должно работать:

class dataWrapperService { 

    constructor($q, $log) { 
     this.$q = $q; 
     this.$log = $log; 
    } 

    data() { 
     console.log(this.$q); 
    } 

    static dataWrapperFactory($q, $log) { 
     dataWrapperService.instance = new dataWrapperService($q, $log); 
     return dataWrapperService.instance; 
    } 
} 

dataWrapperService.$inject = ['$q', '$log']; 

app.factory('dataWrapper', dataWrapperService.dataWrapperFactory); 

Update

Так как уже упоминалось в комментариях код должен работать, так как класс ES6 является конструктором и это то, что ждет angular.service.

Я проверю позже, если я вижу любую другую проблему с вашим кодом.

+0

Я думал, что angular.service взял функцию-конструктор и назвал ее «новой»? – Failpunk

+0

Да, извините, вы правы. Мой код для завода. Я исправлю это. Я не знаю, что не так с вашим кодом. Я видел много примеров, которые понравились в вашем коде. – AWolf

+0

Кажется, что это происходит только с обещаниями. Обновлены приведенные выше примеры. – Failpunk

2

Я знаю, что это поздно, но, возможно, кто-то наткнуться на этом вопросе, как я сегодня с подобными проблемами, так что ...

На самом деле, это не про обещания. Когда вы сделаете это:

let function1 =() => {} 
let function2 = function1 

на самом деле, this объект отличается для функций. Поэтому, когда вы пытаетесь выполнить команду .then(function1), на самом деле function1 копируется в параметр successCallback и его размер this изменен.

Но когда вы используете .then(() => function1()), successCallback получает свою лямбду, и фактическое this из function1 не теряется.

Так что, если вы не знаете, что вы делаете никогда назначить функцию к функции в JavaScript, используйте лямбды вместо

+0

Если вы хотите назначить метод класса обслуживания функции контроллера, сделайте это как '$ scope.isLoggedIn =() => {Auth.isLoggedIn(); }; 'вместо' $ scope.isLoggedIn = Auth.isLoggedIn; '. В противном случае 'this' будет указывать на сам контроллер, а не на класс. Thx для глаза. – arcol

+0

@arcol Я провел несколько часов некоторое время назад, пытаясь понять это, рад, что я могу избавить кого-то от этой боли – SMSk

0

С угловыми 1.6.4, я получаю ошибку, когда я пытаюсь для ввода услуги, которая определена как класс в каком-либо контроллере.

Невозможно вызвать класс как функцию

Так вместо этого, я хочу использовать функцию в качестве службы. Чтобы сохранить его как можно более чистым, я бы экспортировал функцию, которая немедленно возвращает экземпляр анонимного класса. И сделайте это в отдельном файле и импортируйте и используйте эту функцию для создания службы в другом файле.

И поскольку вы просите использовать ES6 с Babel, используйте babel-plugin-angularjs-annotate для безопасного ввода зависимостей, добавив '/* @ngInject */' над экспортируемой функцией.

Инъекционные услуги $q и $log или доступны для класса закрытием. (Нет необходимости передавать их в конструкторе и назначать на это.)

// dataWrapperService.js 
/* @ngInject */ 
export const dataWrapperService = ($q, $log) => new class { 
    constructor() { 
    // do stuff 
    } 

    data() { 
    // $q available through closure 
    console.log($q) 
    } 
}() 

// in your.module.js 
import angular from 'angular' 

import { dataWrapperService } from './dataWrapperService' 

export const YourModule = angular 
    .module('yourmodule', []) 
    .factory('dataWrapper', dataWrapperService) 
    .name