【问题标题】:Issues using $resource without the new operator在没有 new 运算符的情况下使用 $resource 的问题
【发布时间】:2014-05-22 23:52:16
【问题描述】:

我正在尝试在我的应用中使用 Angular Promise API。我有点困惑。我在下面的代码中创建了一个工厂

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'”
但是当我像这样使用'new'关键字时

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

它有效。

我知道构造函数和普通函数的区别。但我不明白为什么 Promise API 只在第二种情况下有效。
谁能帮我理解它是如何工作的?

【问题讨论】:

  • 你试过console.log(transport()); console.log(new transport());吗?看起来transport 只是一个构造函数,可能不会作为函数调用。
  • 这不是“promise api”有效与否,它只是对象创建失败(或失败)。并且访问非对象(undefined)上的属性(方法)注定会失败,无论其预期值是多少。
  • 你能提供一个关于你的问题的 plnkr 演示吗? (将有助于查看更多周边代码)

标签: javascript angularjs ngresource


【解决方案1】:

试试

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

改为。

我知道构造函数和普通函数的区别。 但我不明白为什么 Promise API 只在第二种情况下有效。

因为 API 就是这样设计的。你有实例方法和类方法。

要创建实例,您需要 new 运算符,然后您可以访问实例方法。

$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;
(...)

在文档中简单点击查看源代码显示 class methods 是在 Resource 构造函数上创建的 ADHOC

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

【讨论】:

  • OP 已经有一个可行的解决方案。他只想了解差异,而不是获得第三种(可能无法正常工作)变体。
  • 阅读 Angular 源代码非常有趣,因为他们毫不犹豫地编写超动态、原型更少的代码。作者并不真正关心优化,他们首先关心的是编写 monadic api,$resource 是一个函子。
  • 您的替代方案可能更好地描述为transport.getAll(...).$promise.then(...)
  • 哦,这很有趣。但是你不实例化一个对象并调用transport类本身的方法,他们不会错过一些初始化吗?
  • 如果初始化是在 constructor.getAll 中完成的,则不会。 constructor.getAll !== instance.getAll
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 1970-01-01
  • 2016-12-26
相关资源
最近更新 更多