2016-05-23 36 views
1

我是新來的angularjs。在我的webapp中,我正在嘗試按如下方式與用戶聯繫人合作。將控制器綁定到ajax承諾服務

SERVICE

app.service('Contacts', function ($http,$timeout,$q) { 
    return { 
     getData: function() { 
      var defer = $q.defer(); 
      $http.get('../ListContacts') 
      .success(function(data) { 
       defer.resolve(data); 
      }); 
      return defer.promise; 
     } 
    } 
}); 

ContactsController,OtherControllers

$scope.contactsBook = {}; 
... 
Contacts.getData().then(function(data) { 
    $scope.contactsBook = data; 
}); 

我發現SO本身某處上述方法。我使用它,因爲我不想爲聯繫人使用單獨的模塊。

我可以在網頁加載時獲取數據。我可以通過ajax帖子(來自ContactsController)在服務器上更新我的聯繫人。現在我只需要一種方法在所有控制器中自動更新(/刷新)列表。我怎樣才能做到這一點。

我發現thesethreelinks相關但是作爲一個新手我無法找到我的出路。

+0

如果你正在尋找讓畝當從服務器獲取數據時,多個控制器同步,您需要將數據本身保存在服務/工廠中。你可以通過在角度控制器之間使用'共享數據來查看如何做到這一點' – theaccordance

+0

這意味着我必須改變我的邏輯。沒有其他辦法可以繼續使用當前結構嗎?| – vipanth

+0

@vipanth與你目前的結構相比,你有點受限,因爲你依靠承諾解決方案,這是一個完成的操作。您需要一個可觀察點才能繼續接收更新的數據。但是,如果您將數據存儲更改爲服務,則每個控制器都可以在該數據上註冊一個觀察器,並在數據更改時進行更新。 –

回答

0

雖然這是可以理解的,你可能不希望更新您當前的架構,可能需要稍微調整您的來電如果你想能夠通過服務輕鬆地在控制器之間共享數據。

一種靈活的方法是將數據存儲在您的服務中,並在每個控制器中註冊觀察者。這使您可以從一個控制器(聯繫人控制器)調用服務更新,並將更改反映到所有使用控制器中。請注意,該服務被嘲笑。

你可以找到工作plunker示例here

聯繫服務:

var app = angular.module('app', []);  
app.service('contactsService', function ($http) { 
    var contacts = []; 

    return { 
     loadData: function() { 
      var mockGet = $q.defer(); 

      var data = [ 
       { id: 1, name: 'Jack' }, 
       { id: 2, name: 'Jill' } 
      ]; 

      contacts = data; 
      mockGet.resolve(contacts); 
      return mockGet.promise; 
     }, 
     retrieveNewData: function() { 
      var mockGet = $q.defer(); 

      var data = [ 
       { id: 1, name: 'Jack' }, 
       { id: 2, name: 'Jill' }, 
       { id: 3, name: 'Bob' }, 
       { id: 4, name: 'Susan' } 
      ]; 

      contacts = data; 
      mockGet.resolve(contacts); 
      return mockGet.promise; 
     }, 
     getContacts: function() { 
      return contacts; 
     } 
    } 
}); 

聯繫控制器:

app.controller('ContactsCtrl', ['$scope', 'contactsService', 
    function ($scope, contactsService) { 
    var vm = this; 
    vm.contacts = []; 

    vm.loadData = loadData; 
    vm.retrieveNewData = retrieveNewData; 


    $scope.$watch(angular.bind(contactsService, function() { 
     return contactsService.getContacts(); 
     }), function (newVal) { 
     vm.contacts = newVal; 
    }); 


    function loadData() { 
     contactsService.loadData(); 
    } 

    function retrieveNewData() { 
     contactsService.retrieveNewData(); 
    } 
    } 
]); 

其他控制器:

app.controller('OtherCtrl', ['$scope', 'contactsService', 
    function($scope, contactsService) { 
    var vm = this; 
    vm.contacts = []; 

    $scope.$watch(angular.bind(contactsService, function() { 
     return contactsService.getContacts(); 
     }), function (newVal) { 
     vm.contacts = newVal; 
    }); 
    } 
]); 
+0

謝謝,它的作品 – vipanth

+0

很高興幫助! –

0

你可以做

Contacts.getData().then(function(data) { 
    $scope.contactsBook = data; 
    $scope.$emit('contacts:updated', data); 
}); 

然後,你需要通知有關更新控制器:

$rootScope.$on('contacts:updated', function(e, contacts) { 
    $scope.contacts = contacts; 
}); 

另一種方法

該服務保持電流接觸列表

app.service('Contacts', function ($http,$timeout,$q) { 
    this.currentList = []; 
    this.getData = function() { 
      var defer = $q.defer(); 
      $http.get('../ListContacts') 
      .success(function(data) { 
       defer.resolve(data); 
      }); 
      return defer.promise; 
     } 
}); 

在你的控制器:

Contacts.getData().then(function(data) { 
     $scope.contactsBook = data; 
     Contacts.currentList = data; 
    }); 

在其他控制器:

controller('AnotherController', function($scope, Contacts) { 
    $scope.contacts = Contacts.currentList; 
}); 
+0

謝謝。我會嘗試第二種方法。這看起來更平易近人。 – vipanth

+0

如果數據第二次更新,則第二種方法不會更新。你需要在每個控制器中設置一個觀察者。 –

+0

@Kobi Cohen我試過第二種方法。聯繫人控制器獲取數據,但AnotherController不會(儘管錯字$ scope.contacts而不是$ scope.contactsBook)。我錯過了什麼嗎? – vipanth

-1

如果你要返回一個對象字面,你需要把你的。服務()。工廠()模塊。在這種情況下,我將使用服務模塊。

示例

您的服務。

app.service('Contacts', function ($http,$timeout,$q) { 
    var Contacts = this; 

     contacts.getData = function() { 
      var defer = $q.defer(); 
      $http.get('../ListContacts') 
      .success(function(data) { 
       defer.resolve(data); 
      }); 
      return defer.promise; 
     } 
    } 

return Contacts; 
}); 

然後您需要將此服務器注入到您的ContactsController中。

app.controller('ContactsController', function(Contacts){ 

$scope.data = null; 

$scope.init = function(){ 
Contacts.getData().then(function(response){ 

$scope.data = response; 

}) 
} 

}) 

現在數據可以在DOM使用

<li ng-repeat="x in data">{{x.name}}</li> 
+0

你的第一個陳述其實是不正確的。您也可以從服務返回對象文字。請參閱http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html –

+0

此外,您的示例不解決更新的數據。您的示例中沒有任何內容會第二次更新。這與OP的當前狀態沒有什麼不同。 –

+0

是的,我覺得答案是讓我幾個問題 – vipanth