Search code examples
javascriptangularjsangular-directive

angular directive won't update two-way binding with controller


I have a modal directive that should become visible when a button is pressed. however, the value responsible for determining whether the modal should be open that is two-way bound with the directive does not seem to update. any ideas?

here is the directive JS:

function modalDialogSelect() {
  return {
    restrict: 'AE',
    scope: {
      show: '='
    },
    replace: true,
    transclude: true,
    link: function(scope, element, attrs) {
      scope.dialogStyle = {};
      scope.hideModal = function() {
        scope.show = false;
      };
    },
    templateUrl: "./views/directive_templates/select_modal.html"
  };
 }

directive Inner HTML URL:

<div class='ng-modal' ng-show='show'>
  <div class='ng-modal-overlay' ng-click='hideModal()'></div>
    <div class='ng-modal-dialog' ng-style='dialogStyle'>
      <p>Select New Customer</p>
    </div>
  </div>
</div>

the button to click and open the modal:

<button ng-click='selectCustomer = true;'>SELECT/CREATE CUSTOMER</button>

and the modal-dialog-select directive in my general HTMl

<modal-dialog-select show='selectCustomer'></modal-dialog-select>

any ideas why scope.show isn't updating in my directive? Thanks!


Solution

  • You had a problem in your modal's template that was producing

    Error: Template must have exactly one root element. was: 
    <div class='ng-modal' ng-show='show'>
      <div class='ng-modal-overlay' ng-click='hideModal()'></div>
      <div class='ng-modal-dialog' ng-style='dialogStyle'>
        <p>Select New Customer</p>
      </div>
            </div>
    </div>
    

    After removing the last </div> everything works.

    var app = angular.module("myApp", []);
    
    app.controller('ParentController', function($scope) {
      $scope.selectCustomer = false;
    });
    
    app.directive('modalDialogSelect', function() {
      return {
        restrict: 'AE',
        scope: {
          show: '='
        },
        replace: true,
        transclude: true,
        link: function(scope, element, attrs) {
          scope.dialogStyle = {};
          scope.hideModal = function() {
            scope.show = false;
          };
        },
        templateUrl: "modal.html"
      };
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
    <div ng-app="myApp" ng-controller="ParentController"> 
    
      <p>Flag is: {{selectCustomer}}</p>
      <button ng-click='selectCustomer = !selectCustomer'>SELECT/CREATE CUSTOMER</button>
    
      <modal-dialog-select show='selectCustomer'></modal-dialog-select>
    
    
      <script type="text/ng-template" id="modal.html">
        <div class='ng-modal' ng-show='show'>
          <div class='ng-modal-overlay' ng-click='hideModal()'></div>
          <div class='ng-modal-dialog' ng-style='dialogStyle'>
            <p>Select New Customer</p>
          </div>
        </div>
      </script>
    </div>