programing

각도 - 사용자 지정 메서드를 사용하는 $resource 하위 개체 확장

topblog 2023. 2. 27. 23:21
반응형

각도 - 사용자 지정 메서드를 사용하는 $resource 하위 개체 확장

대부분의 경우 결과는<custom-resource>.query()method는 어레이로, 다음과 같은 (출고시) 코드를 사용하여 일부 메서드(비즈니스 로직)를 사용하여 쉽게 확장할 수 있습니다.

var Data = $resource('http://..');
Data.prototype.foo = function() {return ...};

이것은 다음과 같이 ng-class/ng-class와 함께 사용하기에 적합합니다.

<tr ng-repeat="item in responseData" ng-class="{warning: item.foo()}">..</tr>

문제는 모든 목록 응답이 실제 목록 외에 메타 속성(정렬 정보 등)이 있는 오브젝트에 캡슐화되어 있기 때문에 반환되는 최종 오브젝트는 다음과 같습니다.

{ order_field: "name", items: [{..}, {..},{..}] }

그럼 ng-repeat/ng-class는 어떻게 하면 이전과 같은 것을 만들 수 있을까요?

<tr ng-repeat="item in responseData.items" ng-class="????">..</tr>

이전 방법은 "foo" 메서드가 정의되어 있기 때문에 작동하지 않습니다.responseData가 아닌 경우item물건

목록상의 오브젝트를 인스턴스화하기 위해 사용되는 기본 클래스를 직접 확장할 수 있는 방법이 있습니까?

감사합니다!

전에도 그런 문제를 발견했는데 해결방법은transformResponseJohn Redbetter가 다른 답변에서 말한 바와 같이.

어쨌든 개체 전체를 유지해야 하고 리소스 인스턴스로 채워진 '항목'에 어레이를 포함시켜야 하는 경우 다음과 같은 방법을 사용할 수 있습니다.

John의 답변에서 예를 들어 약간 수정합니다.

angular.module('foo')

  .factory('Post', ['$resource', function($resource) {

    var Post = $resource('/api/posts/:id', { id: '@id' }, {
      query: {
        method: 'GET',
        isArray: false, // <- not returning an array
        transformResponse: function(data, header) {
          var wrapped = angular.fromJson(data);
          angular.forEach(wrapped.items, function(item, idx) {
             wrapped.items[idx] = new Post(item); //<-- replace each item with an instance of the resource object
          });
          return wrapped;
        }
      }
    });

    Post.prototype.foo = function() { /* ... */ };

    return Post;
  }]);

각도 자원 1.1.5를 사용하는 경우(각도 1.0.7에서는 실제로 잘 작동합니다),transformResponse재정의할 때 지정할 수 있는 옵션$resource메서드:

angular.module('foo')
  .factory('Post', ['$resource', function($resource) {

    var Post = $resource('/api/posts/:id', { id: '@id' }, {
      query: {
        method: 'GET',
        isArray: true,
        transformResponse: function(data, header) {
          var wrapped = angular.fromJson(data);
          return wrapped.items;
        }
      }
    });

    Post.prototype.foo = function() { /* ... */ };

    return Post;
  }]);

이렇게 하면 래핑된 응답에서 항목을 수동으로 꺼낼 필요가 없어지고 각 항목은 다음 인스턴스가 됩니다.Post에 액세스 할 수 있는.foo방법.다음과 같이 쓸 수 있습니다.

<tr ng-repeat="post in posts" ng-class="{warning: post.foo()}">..</tr>

이 문제의 단점은 내부 항목이 아닌 응답의 외부 필드에 액세스할 수 없다는 것입니다.메타데이터를 보존할 방법을 찾는 중입니다.

이것은 오래된 질문이지만, 저도 방금 이 문제에 부딪혔어요.gargc의 솔루션은 올바른 접근법이지만 개선점이 있습니다. transformResponse에 전달되는 배열을 받아들입니다.$http서비스.변환 기능을 완전히 대체하는 대신 변환을 기본값으로 추가하여 필요한 업데이트만 수행할 수 있습니다.

angular.module('foo')
    .factory('Post', function ($resource, $http) {
        var Post = $resource('/api/posts/:id', { id: '@id' }, {
            query: {
                method: 'GET',
                isArray: false,
                transformResponse: $http.defaults.transformResponse.concat(function(data, header) {
                    angular.forEach(data.items, function(item, idx) {
                        data.items[idx] = new Post(item);
                    });
                    return data;
                })
            }
        });

        Post.prototype.foo = function() { /* ... */ };

        return Post;
    });

메타데이터를 헤더에 넣을 수 있습니다.저는 항상 거기에 페이징 데이터를 넣습니다.그렇게 하면 쿼리가 어레이를 반환할 수 있습니다.그것은 좋은 일이라고 생각합니다.쿼리는 단일 데이터가 아니라 데이터 배열을 반환해야 합니다.

언급URL : https://stackoverflow.com/questions/17134401/angular-extending-resource-subobject-with-custom-methods

반응형