Инициализация ресурса AngularJS $с помощью встроенного JSON

Я использую ресурс AngularJS '$ для извлечения и обновления объекта. Чтобы сохранить обратную поездку при загрузке страницы, у меня есть объект JSON в переменной на странице. Как я могу инициализировать $resource этими данными, а не вызывать $get?

Ответ 1

Вы можете использовать new для создания экземпляров ресурсов, созданных с помощью $resource:

window.somePreloadedJson = {
  id: 1,
  name: 'lancelot',
  quest: 'holy grail',
  color: 'blue',
};

app.factory('myResource', function($resource) {
  return $resource('/my/fake/:id', { id: '@id' });
});

...

$scope.resource = new myResource(window.somePreloadedJson);

Вот пример этой техники на jsFiddle, который показывает, что $save, $delete и т.д. работают, как ожидалось, на созданный экземпляр. (Некоторый код отладки был добавлен для выхода из HTTP-запросов, а не для их создания, поэтому вы можете увидеть, какие запросы были бы сделаны на странице.)

Ответ 2

Вы можете использовать angular-mocks.js script, доступный здесь. Этот script позволяет перехватывать служебные вызовы и подставлять ответы во время выполнения, что очень полезно для целей тестирования.

Например, с учетом службы:

app.factory('MyService', ['$resource', function($resource) {
    return $resource('http://myservice/service', {}, {
        get: {
            method:'GET', 
            params:{}, 
            isArray:false
        }
    });
}]);

его можно перенаправить следующим образом:

app.config(function($provide) {
    $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
});

app.run(function($httpBackend) {
    $httpBackend.whenGET(new RegExp(".*/myservice/service.*")).respond(200, mockData.fake);
    ...
}

где mock data определяется где-то следующим образом:

var mockData = new Object();
mockData.fake = ...

Чтобы активировать фальшивую службу, просто включите angular -mocks script и вышеупомянутые определения, чтобы переключиться на обычный, просто закомментируйте или удалите их.

Ответ 3

Оскорбительно расстраивает меня, что на это лучше не отвечают. Вот мое решение. Я не знаю, соответствует ли он хромому или нет, но это работает для меня:

# Loading json data from the document into angular seems to be a pain.
# The sole purpose of this controller is to make that easier.

# Let say you want to load up the following JSON: [{"name": "Joe", "id": 1}]
# AND you have an angularjs service called People with a list
# You would do the following:

# <any_element ng-controller='JsonDataController' data-json='[{"name": "Joe", "id": 1}]' data-service='People' data-binding='list'></any_element>
# The controller would then set People.list = JSON.parse($attrs.json)

# And that all there is to it.

window.JsonDataController = ['$scope', '$attrs', '$injector', ($scope, $attrs, $injector) ->
  service = $injector.get($attrs.service)
  attributeName = $attrs.binding
  service[attributeName] = JSON.parse($attrs.json)
  ]

Ответ 4

Вы можете использовать пользовательский $cacheFactory для инициализации ресурса $с данными.

Скажем, у вас есть:

window.initData = {
    '/request1': 'a',
    '/request2': [1, 2, 3],
    '/request3': {c: 'c', d: 'd'}
};

Сначала создайте пользовательский кеш factory:

angular.module('app').factory('PreloadedCache', function($cacheFactory, $window) {
    var PreloadedCache = $cacheFactory('preloadedCache');

    // Pre-populating the $resource cache
    angular.forEach($window.initData, function(item, key) {
        PreloadedCache.put(key, item);
    });

    // Overwrite the put cache function - prevent saving in two places
    PreloadedCache.put = function() {};

    return PreloadedCache;
});

Затем объявите свойство кеша в действии ресурса (из документов):

cache - {boolean | Cache} - Если true, кеш-адрес по умолчанию $http будет использоваться для кэширования запроса GET, иначе если экземпляр кеша, построенный с $cacheFactory, этот кеш будет использоваться для кэширования.

{action1: {method:?, params:?, cache: PreloadedCache, ...},
action2: {method:?, params:?, isArray:?, headers:?, cache: PreloadedCache, ...},
...}