Implicitly bind a controller to a directive via HTML code

I have an angular controller that does its normal actions (on request, calls a service, gets data, and stores in its scope). Separately, I have a directive whose purpose is to make the sidebar slide menu show and hide (with a little animation). The menu list is associated with the result of the controller action.

The idea is to click on a button elsewhere on the screen: 1. the controller action will be executed 2. on success the directive will be prompted to go to the menu

I want this to happen without a controller or directive having the slightest knowledge of each other.

Is it possible to write an anchor expression in HTML code where after changing the list of menu items it is called by a directive method show()

?

+3


source to share


2 answers


I managed to solve this problem by introducing a second, service directive called onModelChange

. It uses ngModel

to listen for changes in the model, and when it does, it calls the method in the first directive, which is passed as a reference parameter.

index.html

<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <script data-require="angular.js@1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="MainController">
    <a href="#" ng-click="doAction()">Call the controller</a>

    <h2 ng-show="controllerCalled">controller called</h2>

    <a custom-directive ng-click="show()">
      <h2 ng-show="directiveCalled">directive called</h2>
      <h2 ng-show="!directiveCalled">directive NOT called</h2>
    </a>

    <div ng-model="items" on-model-change="show()">
      <div ng-repeat="item in items" >
        <p>{{item}}</p>
      </div>
    </div>

  </body>

</html>

      



script.js

var myApp = angular.module('myApp', []);

myApp.controller('MainController', ['$scope',
  function($scope) {
    $scope.doAction = function() {
      $scope.controllerCalled = true;
      $scope.items = [1, 2, 3, 4, 5, 6];
    }
  }
]);

myApp.directive('customDirective', function() {
  return {
    restrict: 'A',
    link: function($scope) {
      $scope.show = function() {
        $scope.directiveCalled = true;
      }
    }
  }
});

myApp.directive('onModelChange', function() {
  return {
    restrict: 'A',
    scope: {
      model: '=ngModel',
      onModelChange: '&'
    },
    link: function($scope, element, attrs) {
      $scope.$watch('model', function(oldM, newM) {
        if (oldM != newM) {
          $scope.onModelChange();
        }
      })
    }
  }
});

      

+1


source


Yes, the correct way is to create a service (or factory) that contains methods and data, shared by directive and scope, and managed by a controller.



Such a service will be injected into your directive and your controller.

0


source







All Articles