Угловой ресурс перезагрузки, за которым ведется наблюдение


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

У меня есть ресурс

Book = $resource("/books/:id", {id: "@id"});
book = Book.get(1);

Я хочу обновить объект, чтобы получить изменения с сервера. Я знаю, что могу сделать это, повторив book = Book.get(book.id), но это будет означать, что все на странице, которая смотрит book, будет временно обнуляться до тех пор, пока запрос не вернется и функции, которые работают с ним, могут аварийно завершиться.

Я хочу добавить метод перезагрузки в экземпляры, который обновляет любые измененные поля как только запрос возвращается с сервера. Моя лучшая попытка на данный момент:

$reload = function() {
    var model = this;

    Book.get(model.id, function(data) { // success
      angular.forEach(data, function(value, key) {
          model[key] = value;
      }
    }
}

Два вопроса а) это "угловой" способ сделать это, или есть более элегантный способ? а) как добавить этот метод $ refresh при определении ресурса, чтобы он включался в каждый созданный экземпляр?

3 3

3 ответа:

Попробуйте расширить его прототип:

var Book = $resource("/books/:id", {id: "@id"});
Book.prototype.reload = function(callback) {
    return this.get(this.id, callback);
}

var book = Book.get(1);
book.reload(function(data){console.log(data);});

Спасибо: @mathew-berg (Мэтью Берг) за исправление моего кода.

Пара мыслей:

  1. как структурирована ваша модель? Из документа $resource docs: "наличие пустого объекта не приводит к отрисовке, как только данные поступают с сервера, объект заполняется данными, и представление автоматически повторно отрисовывает себя, показывая новые данные."
  2. Откатите ваше собственное взаимодействие API в угловой службе, чтобы вы могли управлять асинхронным поведением:

    yourApp.factory('BookService', function($q) {
    
       //Other API calls here
    
       function reload() {
          var deferred = $q.defer();
    
          $http.get('/someUrl').
          success(function(data, status, headers, config) {
             //Massage your data here... then
             deferred.resolve(data);
          }).
          error(function(data, status, headers, config) {
             deferred.reject('There was a problem updating the books');
          });
    
          return deferred.promise;
       }
    
       return {
          reload: reload
       }
    });
    
    //In your conttroller or directive that holds your model
    books = BookService.reload();
    

Решение@num8er даже не будет работать без сбоя для меня. Может быть, мы используем разные версии angular? (Я на 1.4.x в данный момент.) В частности, я должен был изменить get() на $get(), но я также хотел перезагрузить объект, не проходя в пользовательском обратном вызове, чтобы захватить его отовсюду, где я вызвал перезагрузку, поэтому я добавил Это во внутреннюю часть.

Я должен был сделать:

var Book = $resource("/books/:id", {id: "@id"});
Book.prototype.reload = function() {
    var book = this;
    book.$get(book.id, function (new_book) {
        book = new_book;  // replace old book object with newly reloaded one
    });
};

var book = Book.get(1);
book.reload();