Проблемы с использованием $resource без нового оператора

Я пытаюсь использовать API обещаний Angular в своем приложении. И я был немного сбит с толку. Я создал фабрику, как в коде ниже

factory('transport', function ($resource) {
    var baseUrl = "http://aw353/WebServer/odata/Payments";
    return $resource("", {},
        {
            'getAll': { method: "GET",params: {svcUrl:"@svcUrl"}, url: baseUrl + ":svcUrl" },
            'save': { method: "POST", params: {svcUrl:"@svcUrl"}, url: baseUrl+ "(:svcUrl)" },
            'update': { method: 'PUT', params: {svcUrl:"@svcUrl", key: "@key" }, url: baseUrl+ "(:svcUrl)" + "(:key)"},
            'query': { method: 'GET', params: {svcUrl:"@svcUrl", key: "@key" }, url: baseUrl +"(:svcUrl)" + "(:key)"},
            'remove': { method: 'DELETE',  params: {svcUrl:"@svcUrl", key: "@key" }, url: baseUrl + "(:svcUrl)" + "(:key)"}
        });
});

Я использую эту фабрику в контроллере, и когда я реализую такую ​​​​функцию

var getData = function () {
    (transport()).$getAll({svcUrl:"//BasicSettings"})
        .then(function (data) {
            $scope.DataSource = data.value[0];
            console.log($scope.DataSource.SystemName);
        });
}();

происходит сбой, и я получаю сообщение об ошибке "Невозможно прочитать свойство $getAll неопределенного"
Но когда я использую ключевое слово "новое", подобное этому

var getData = function () {
    (new transport()).$getAll({svcUrl:"//BasicSettings"})
        .then(function (data) {
            $scope.DataSource = data.value[0];
            console.log($scope.DataSource.SystemName);
        });
}();

оно работает.

Я знаю разницу между функцией-конструктором и обычной функцией. Но я не понимаю, почему обещание API работает только во втором случае.
Может ли кто-нибудь помочь мне понять, как это работает?


person alinaish    schedule 22.05.2014    source источник
comment
Вы пробовали console.log(transport()); console.log(new transport());? Похоже, transport — это просто конструктор, который нельзя вызывать как функцию.   -  person Bergi    schedule 22.05.2014
comment
Это не обещание API, которое работает или нет, это просто создание объекта, которое терпит неудачу (или нет). И тогда доступ к свойству (методу) не-объекта (undefined) обречен на неудачу, независимо от того, каково его ожидаемое значение.   -  person Bergi    schedule 22.05.2014
comment
Можете ли вы предоставить демо-версию plnkr по вашей проблеме? (было бы полезно увидеть больше окружающего кода)   -  person s_hewitt    schedule 22.05.2014


Ответы (1)


Пытаться

transport.getAll(...).$promise.then(...)

вместо.

Я знаю разницу между функцией-конструктором и обычной функцией. Но я не понимаю, почему обещание API работает только во втором случае.

Хорошо, потому что API разработан таким образом. У вас есть методы экземпляра и методы класса.

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

Метод $resoure() является фабрикой для расширения "$resource" и возвращает функцию-конструктор, которая имеет методы класса, а экземпляры этой функции-конструктора имеют методы экземпляра.

function Resource(value) {
    shallowClearAndCopy(value || {}, this);
}

forEach(actions, function (action, name) {
    var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);

    Resource[name] = function (a1, a2, a3, a4) {
        var params = {}, data, success, error;
(...)

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

https://github.com/angular/angular.js/blob/master/src/ngResource/resource.js#L492

person mpm    schedule 22.05.2014
comment
У OP уже есть рабочее решение. Он хочет только понять разницу, а не получить третий (возможно, нерабочий) вариант. - person Bergi; 22.05.2014
comment
чтение углового исходного кода очень интересно, потому что они не колеблясь пишут гипердинамический код без прототипов. Авторы на самом деле не заинтересованы в оптимизации, их первая забота - написание монадического API, $resource - это функтор. - person mpm; 22.05.2014
comment
Ваш вариант может быть лучше описан как transport.getAll(...).$promise.then(...) - person Marc Kline; 22.05.2014
comment
О, это интересно. Но вы не создаете экземпляр объекта и не вызываете методы самого класса transport, не пропустят ли они некоторую инициализацию? - person Bergi; 22.05.2014
comment
нет, если инициализация выполняется внутри конструктора.getAll. конструктор.getAll !== instance.getAll - person mpm; 22.05.2014
comment
+1 для $resource и возвращает функцию конструктора Вот почему new transport() работает, а transport() нет. См.: jsfiddle.net/8Pd4g/4. - person s_hewitt; 22.05.2014