0

I am just starting out with the MEAN stack and not really sure what the optimal way to share data and detect change in another controller would be. I have the text/search input in the header, logic for that in one controller (TypeheadController) and after someone either selects a value from the typeahead/autocomplete list or presses the search button I wish for Searchresultscontroller to detect a change for a property on the startSearchService and use that value to load search results.

The main layout.server.html template

<body>

<header ng-controller="HeaderController">
<nav></nav>
<div ng-controller="TypeaheadController">
<input type="text" typeahead-on-select="onSelect($item, $model, $label)" />
</div>
</header>

//**this is where angular-ui-router.js will load templates into.** 
<section data-ui-view></section>

</body>

client.searchresults.html template.

<div ng-controller="SearchresultsController">
**//the SearchresultsController will pull JSON search result data and populate this template. Presentation logic omitted for clarity**
</div>

startSearchService

angular.module('myapp').service('startSearchService', function() {

this.searchString = "";


});

TypeaheadController

var TypeaheadController = function($scope, $http, startSearchService)
{
  //function that pulls and maps name suggestion for typeahead goes here.

  //Upon user selecting a typeahead suggestion, update the property on the service instance. OnSelect will fire when user selects suggestion.

$scope.onSelect = function(item, model, label) {

  startSearchService.searchString = item;

  }

};

SearchresultsController

var SearchresultsController = function($scope, $http, startSearchService)
{
  //This controller should make the actual request to pull search results
 // after which the state will be changed to /searchresults/ and the       //client.searchresults.html template will be loaded and populated. Most Typeahead //directives and other code omitted for clarity.

//Upon user selecting a typeahead suggestion update the properties on the    //service. 
//OnSelect will fire when user selects suggestion.

**//I need logic to detect change in startSearchService.searchString and then I will use that value to pull in search results. The below $on function does not work and it's wrong way to watch for change**

startSearchService.searchString.$on('change', function(ev, args) {

//Pull data from Server
//then change $location to /searchresults/ and client.searchresults.html will    //load and $scope data will be binded to it.


});

};
LaserBeak
  • 3,257
  • 10
  • 43
  • 73
  • You can use service or [scope inheritance](http://stackoverflow.com/q/27696612/1679310) - Service will live for ever, you have to clean it properly on state hierarchy/family change. Scope inheritance is tightly coupled, and/but is cleaned when navigating out... – Radim Köhler Oct 31 '15 at 05:57
  • @RadimKöhler I can't use scope inheritance because the controllers in question are not nested. Only $rootScope. – LaserBeak Oct 31 '15 at 06:56

1 Answers1

1

Make your startSearchService expose functions rather than a field:

angular.module('myapp').factory('startSearchService', function() {

    var searchString = "";

    return {
        set: function(s) {
            searchString = s;
        },
        get: function() {
            return s;
        }
    };
});

Then make it broadcast an event every time the searchString is modified:

angular.module('myapp').factory('startSearchService', function($rootScope) {

    var searchString = "";

    return {
        set: function(s) {
            searchString = s;
            $rootScope.$broadcast('searchStringChanged');
        },
        get: function() {
            return s;
        }
    };
});

From your TypeaheadController, call the set() function to modify the search string.

From your SearchresultsController, listen on the 'searchStringChanged' event:

$scope.$on('searchStringChanged', function() {
    var searchString = startSearchService.get();
    // TODO do something with the new searchString
});
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255