0

I have different views each created by a different controller. At a particular time only one of the views is visible.

I want to switch from one view to another view through a function of the controller of the first view and after that I want to call a method of the second view controller.

My problem is how should I call this method in an angular way?

I know the possiblity using $broadcast and $on but that smells a little bit.

The other choice ist to find the scope in the dom and calling the method via scope. But that is even more ugly.

What is the best solution?

dec
  • 594
  • 1
  • 9
  • 18
  • Are you using ngRoute or UI Router...? – Matías Fidemraizer Jun 03 '15 at 19:51
  • Wouldn't you just use routing & `$location.path('/whatever');` ? – Mark Pieszak - Trilon.io Jun 03 '15 at 19:52
  • If i understandyou question correctly you could listento view change [event from routers](https://docs.angularjs.org/api/ngRoute/service/$route#events). Or for a general pub/sub communication you could as well [create a pub/sub service](http://stackoverflow.com/questions/25274563/angularjs-communication-between-directives#answer-25274665).Either way it will be via event/callback mechanism, which does not smell that bad considering lose coupling that you can get.Even with patterns like [`flux`](https://facebook.github.io/flux/docs/overview.html#content) eventing is used via dispatcher/emitters. – PSL Jun 03 '15 at 19:56
  • Routing is not the problem, but no I do not use a router. It`s more like having different tabs in a view and if you select a tab the corresponding controller is created and the view is rendered. The problem is to call a method of the target/second view controller inside the controller of the actual/first view. The switch from one view to the other is simply done with a change of the active view model. – dec Jun 03 '15 at 20:00

3 Answers3

0

You can use services to communicate between controllers. While you could create a generic shared service to have a central point to subscribe to and broadcast events, services are easier to maintain over time.

Vlada
  • 258
  • 4
  • 8
  • Yes a service seems to be a good idea, but is this only possible using events? And how can I trigger a method in the controller that sets the focus to an input field and selects its content? – dec Jun 03 '15 at 20:07
0

You can use Angular Routing

Check out the documentation. This is an excerpt from the documentation. You can make links like

<a href="#/phones">Link</a>

For the first route and so on.

phonecatApp.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/phones', {
        templateUrl: 'partials/phone-list.html',
        controller: 'PhoneListCtrl'
      }).
      when('/phones/:phoneId', {
        templateUrl: 'partials/phone-detail.html',
        controller: 'PhoneDetailCtrl'
      }).
      otherwise({
        redirectTo: '/phones'
      });
  }]);
  • Its more like having different tabs inside a view and I want to switch programatically from the first to the second and after that call a method of the seccond view. – dec Jun 03 '15 at 20:08
  • You can check out [Angular UI Bootstrap's](http://angular-ui.github.io/bootstrap/) tab implementation. [Click here](http://plnkr.co/edit/?p=preview) for the code – Anand Singh Kunwar Jun 04 '15 at 03:18
  • @dec Did you check it out? – Anand Singh Kunwar Jun 08 '15 at 11:20
  • Yes, but I already had tabs. My problem was to call a function in a different controller ... Or am I not getting the point. I have posted my solution above. – dec Jun 08 '15 at 11:32
0

Okay it is done and simpler as expected.

The idea is to use a service used in both views (controllers), that contains a 'execution boolean'.

The first view set the boolean to true, the second set a watch on this boolean and therefore is called and can call the desired method.

In the service:

trigger: function(name) { model[name] = true; },
setTriggerWatch: function(scope, name, callback) {
    scope.$watch(function value() {
        return model[name];
    }, function listener(newValue, oldValue) {
        if (newValue) {
            callback();
        }
    });
},

In the destination controller:

sessionData.setTriggerWatch($scope, 'createSession', function callCreateSession() {
    _createSession();
});

In the source controller:

sessionData.trigger('createSession');
dec
  • 594
  • 1
  • 9
  • 18