7

是否可以向 ngResource 添加虚拟属性?我创建了这样的服务

app.factory('Person', ['$resource', function($resource) {

  return $resource('api/path/:personId', {
    personId: '@_id'
      }, {
        update: {
          method: 'PUT'
        }
      });
}])

Person有一个属性name和一个属性surname
我想通过添加一个返回fullname的虚拟属性来检索. 我知道我可以将它添加到控制器中,但是将它添加到服务中会使其更便携。我尝试过这样的事情fullnameresource.name + resource surname

app.factory('Person', ['$resource', function($resource) {

  return $resource('api/path/:personId', {
    personId: '@_id'
      }, {
        update: {
          method: 'PUT'
        },
    fullname: function(resource){
      return resource.name + ' ' + resource.surname;
    }
  });
 });
}])

但它不起作用。

4

4 回答 4

4

根据文档,$resource返回一个构造函数。您可以利用prototype构造函数的常用功能来添加成员,即:

var Person = $resource('api/path/:personId', {
            personId: '@_id'
        }, {
            update: { method: 'PUT' }
        }); // same as the 1st snippet from the question

Person.prototype.xxxx = ...;

return Person; // from your Angular service

在前面的示例xxxx中,可以是原型中通常允许的任何内容。如果你想要的实际上是一个派生属性,即一个始终反映nameandsurname属性的 JS 属性,那么你需要一个相当新的浏览器,它支持Object.defineProperty()并将Person.prototype上面的行替换为:

Object.defineProperty(
    Person.prototype,
    "fullname",
    {get: function() { return this.name + " " + this.surname; }}
);
于 2014-06-10T10:25:09.453 回答
4

您可以尝试拦截来自 Person 资源的响应并增加响应。像这样:

app.factory('Person', ['$resource', function($resource) {
  function getFullName(){
      return this.name + ' ' + this.surname;
  };

  return $resource('api/path/:personId', {
    personId: '@_id'
      }, {
        update: {
          method: 'PUT'
        },
        'get': {method:'GET', isArray:false,interceptor:{
              'response': function(response) {
                  response.fullname = getFullName; //augment the response with our function
                  return response;
               }
         }}
      });
}]);
于 2014-06-13T13:20:46.293 回答
2

如果您只需要派生属性用于显示目的,您可以创建一个显示过滤器,而不是使用冗余数据加载您的模型:

app.filter('personFullName', function() {
  return function(person) {
    return person.name + " " + person.surname;
  };
})

然后在模板中引用过滤器:

<div>
  <p>{{person | personFullName}}</p>
  <p>- should match -</p>
  <p>{{person.name}} {{person.surname}}</p>
</div>
于 2014-06-12T00:07:36.813 回答
1

Khanh TO让我找到了一个可行的答案,但是,正如这个 Angular 票证中所解释的,在拦截器中,你必须处理并返回response.resource而不是response.

这是一个解决方案(适用于 Angular 1.4):

app.factory('Person', ['$resource', function($resource) {

return $resource(
    'api/path/:personId',
    {personId: '@_id'},
    {
        update: {method: 'PUT'},
        get: {
            method: 'GET',
            isArray: false,
            interceptor: {
                response: function(response) {
                    var resource = response.resource;
                    resource.fullname = resource.name + ' ' + resource.surname;
                    return resource;
                }
            }
        }
    });
}]);
于 2016-01-14T14:54:59.527 回答