2014-09-11 2 views
0

я не могу показаться, чтобы выяснить, какой путь идти об этой проблеме:доля и сохранить данные из нескольких контроллеров в angularjs

Я получил несколько угловых контроллеры, все они нуждаются в пользовательский объекте, который они могут манипулировать с, и каждый раз, когда ему манипулируют, «новые» данные также должны отсутствовать и в других контроллерах. В то же время мне нужно сохранить этот пользовательский объект в базе данных для последующего извлечения (так что функция автоматического сохранения при изменении данных на объекте пользователя)

Но я не могу понять, следует ли мне использовать фабрику или службу для хранения этого пользовательского объекта и как я могу получить эту фабрику/услугу, чтобы сохранить пользователя при изменении через API.

Я прочитал этот пример Sharing ajax data between multiple controllers in angular using service, где он хочет выполнить некоторые из тех же вещей, но часть API и автоматическое сохранение async действительно дают мне проблемы!

Нижняя строка: у меня есть несколько контроллеров, которым необходим пользовательский объект с сервера. И эти контроллеры манипулируют одним и тем же объектом-пользователем, и после каждой манипуляции (возможно, с некоторым отказом) я хочу сохранить объект в базе данных через API.

(первый из, я подумал о просмотре объекта в службы/завода, но узнал, что я не мог :()

Можете ли вы, ребята, мне точку в правильном направлении?

ответ

1
  1. Вы создаете объект User (либо через сервис, либо на заводе).
  2. Вы вводите этот объект в любой контроллер, который хочет взаимодействовать с ним.
  3. $watch Этот объект (изнутри самой службы, если вы считаете, что эта функциональность является основной частью объекта User) и обновлять бэкэнд при обнаружении изменения (опционально с отклонением).
  4. Для $watch Что-то изнутри службы, вы можете ввести услугу $rootScope.
  5. Имейте в виду, что (в реальном приложении) вам необходимо учитывать ошибки и угловые шкафы. Например. что произойдет, если пользователь перейдет от страницы до того, как пройдет период дебюта и т. д.

Ниже приведена наивная реализация ПОС. В реальном мире вы, вероятно, захотите использовать модуль (например, упомянутый Mikke) и обернуть вокруг него сервис yur, чтобы сохранить много кода шаблона во время взаимодействия с вашим источником данных RESTful.


Демонстрационный сервис может выглядеть следующим образом:

.factory('User', function ($q, $rootScope, $timeout) { 
    var apiEndpoint = '/api/user'; 
    var guest = { 
     username: 'Guest', 
     email : null, 
     loggedIn: false 
    }; 
    var user = {}; 

    user.login = function (credentials) { 
     user.logout(); 

     // In real app: Make a login request 
     var request = $q.defer(); 
     $timeout(function() { 
      user.username = 'ExpertSystem'; 
      user.email = '[email protected]'; 
      user.loggedIn = true; 
      request.resolve(user); 
     }, 1000); 

     return request.promise; 
    }; 

    user.logout = function() { 
     // In real app: Make a logout request 
     angular.extend(user, guest); 
    }; 

    user.update = function() { 
     // In real app: Make a request to update user info 
     alert('Updating the backend...'); 
    }; 

    var updateTimeout; 
    user.updateWithDebounce = function() { 
     $timeout.cancel(updateTimeout); 
     updateTimeout = $timeout(function() { 
      user.update(); 
     }, 1000); 
    }; 

    $rootScope.$watchCollection(function() { 
     return user; 
    }, function (newValue, oldValue) { 
     var shouldUpdate = newValue && newValue.loggedIn && 
          oldValue && oldValue.loggedIn; 
     // Immediate backend update 
     //if (shouldUpdate) user.update(); 

     // Debounced backend update (1 sec debounce) 
     if (shouldUpdate) user.updateWithDebounce(); 
    }); 

    user.login(); 

    return user; 
}); 

См, также, это short demo.

+0

Отличный пример. После попытки смешивания я начал все заново, и взял ваш код и смешал мой. И он работал отлично. Я просто должен привыкнуть к тому, что мой объект пользователя в контроллерах имеет на нем как свойства, так и методы. Спасибо большое! – Ngschumacher

0

При совместном использовании данные между контроллерами - это способ пойти. У вас, похоже, уже есть хорошее представление об этом.

Для сохранения пользователя после каждой манипуляции я не понимаю, в чем проблема. Создайте метод изменения пользователя, после чего вы можете сделать сравнение объектов. Если есть разница, отправьте запрос PUT на api.

+0

Но где я должен создать такое сравнение? В моей маленькой фантазии я бы хотел сделать что-то подобное в контроллере: $ scope.user.name.lastName = "Hansen"; (или даже привязка ng-модели к полю ввода) И затем в сервисе «ловит» изменение и сохраняет данные через фабрику, я полагаю. Но как служба может видеть, что произошли изменения? Я контроллер, я бы $ watch, но я не могу на службе. – Ngschumacher

+0

, если услуга введена в ваш контроллер, вы можете легко получить к ней доступ. ServiceName.user.name.lastName = 'abc' или, возможно, даже лучший пользовательский объект ServiceName.user.editName ({lastName: 'abc}). Объект может содержать функцию сравнения, которую функция редактирования могла бы вызвать после применения изменения. – Cathal

1

Независимо от того, создавать ли сервис или завод, проблема дизайна.

Вы, наверное, хотите посмотреть на такие библиотеки как $resource, Restangular или ThickM, который поможет вам создать услуги, которые касаются ваших моделей API конечных точек для извлечения и сохранения.

Асинхронное автоматическое сохранение может быть разрешено либо в сервисе, либо на контроллерах.

Раскрытие информации: Я являюсь автором ThickM.

0

Я рекомендую вам всегда делиться данными между контроллерами (а также директивами) с помощью Сервиса/Фабрики и вводить их с обеих сторон.

После этого просто используйте функцию разрешения обещаний, чтобы обновить значение услуги.

app.factory('SharedService', function() { 
    return { 
    sharedObject: { 
     value: '', 
     value2: '' 
    } 
    }; 
}); 

app.controller('FirstCtrl', function($scope, SharedService) { 
    $scope.model = SharedService.sharedObject; 
}); 

app.directive('myDirective',['SharedService', function(SharedService){ 
    return{ 
    restrict: 'E', 
    link: function(scope){ 
     scope.model = SharedService.sharedObject; 
    }, 
    template: '<div><input type="text" ng-model="model.value"/></div>' 
    } 
}]); 

Вот это plunkr показывает, как это можно сделать: http://plnkr.co/edit/Q1VdKJP2tpvqqJL1LF6m

+0

похоже законный. Хотя у меня возникла проблема, что заводские данные извлекаются async, и кажется, что контроллеры не могут получить извлеченные данные с $ http.get моего завода. – Ngschumacher

Смежные вопросы