简体   繁体   中英

scope variable isn't reflected in directive

I'm trying to fill the body attribute, so my module will print it as it's body part, yet I have no idea why it's not working, even I tried $scope.$apply() in several places.

 var app = angular.module('ClientLogger', ['ngRoute']) app.controller('global', function($scope, $compile) { $scope.window = window $scope.sampletext = "sampleText"; $scope.showModal = false; $scope.toggleModal = function(text) { $scope.text = text; $scope.showModal = !$scope.showModal; }; }); app.directive('modal', function() { return { template: '<div class="modal fade">' + '<div class="modal-dialog">' + '<div class="modal-content">' + '<div class="modal-header">' + '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>' + '<h4 class="modal-title">{{ title }}</h4>' + '</div>' + '<div class="modal-body" ng-transclude> {{ body }} </div>' + '</div>' + '</div>' + '</div>', restrict: 'E', transclude: true, replace: true, scope: true, link: function postLink(scope, element, attrs) { scope.title = attrs.title; scope.body = attrs.body; scope.$watch(attrs.visible, function(value) { if (value == true) $(element).modal('show'); else $(element).modal('hide'); }); $(element).on('shown.bs.modal', function() { scope.$apply(function() { scope.$parent[attrs.visible] = true; }); }); $(element).on('hidden.bs.modal', function() { scope.$apply(function() { scope.$parent[attrs.visible] = false; }); }); } }; }); 
 <body ng-app='ClientLogger' ng-controller='global'> <a class="btn btn-default" ng-click="toggleModal(sampletext)"> sample </a> <modal title="Message Details" body="{{text}}" visible="showModal"></modal> </body> 

As you can see, after i click the link, it will change the variable $scope.text and it will reflect to the modal. But I can't manage to do it. Since I#m very new about this Angular, I still have troubles about understanding its mechanics, so any specific details will be really good for me. Any recommendations?

When you retrieve your attrs.body , you are retrieving undefined data.

You can use a Factory to share your data. You have to know that all angular services are singletons, so there is only one instance of a given service.

Thanks to this, you can easily share your data between your controller and your directive.

So when you will trigger an action in your Controller, you will set your data into your factory, then you can retrieve your data into your directive.

Controller

  (function(){

  function Controller($scope, Service) {

    $scope.myText = 'sample';

    $scope.showModal = false;

    $scope.toggleModal = function() {
      //Set the myText value by using our Service.set() method
      Service.set($scope.myText);
      $scope.showModal = !$scope.showModal;
    };

  }

  angular
  .module('app', [])
  .controller('ctrl', Controller);

  })();

Service

(function(){

  function Service(){

    var data;

    function set(value){
      data = value;
    }

    function get(){
      return data;
    }

    return {
      get: get,
      set: set
    };

  }

  angular
    .module('app')
    .factory('Service', Service);

})();

Directive

(function(){

  function modal(Service) {
    return {
        template: '<div class="modal fade">' +
          '<div class="modal-dialog">' +
          '<div class="modal-content">' +
          '<div class="modal-header">' +
          '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>' +
          '<h4 class="modal-title">{{ title }}</h4>' +
          '</div>' +
          '<div class="modal-body"> {{ body }} </div>' +
          '</div>' +
          '</div>' +
          '</div>',
        restrict: 'E',
        transclude: true,
        replace: true,
        scope: true,
        link: function (scope, element, attrs) {

          scope.title = attrs.title;

          scope.$watch(attrs.visible, function(value) {
            value
            //Retrieve your data by using Service.get() method, and show our modal
            ? ( scope.body = Service.get(), $(element).modal('show') )
            : $(element).modal('hide')
          });

          $(element).on('shown.bs.modal', function() {
            scope.$apply(function() {
              scope.$parent[attrs.visible] = true;
            });
          });

          $(element).on('hidden.bs.modal', function() {
            scope.$apply(function() {
              scope.$parent[attrs.visible] = false;
            });
          });
        }

      };
  }

angular
  .module('app')
  .directive('modal', modal);

})();

Then, you can call your directive into your HTML.

HTML

  <body ng-app='app' ng-controller="ctrl">
    <input type="text" ng-model="myText">
    <a class="btn btn-default" ng-click="toggleModal()"> sample </a>
    <modal title="Message Details" visible="showModal"></modal>
 </body>

You can see the Working Plunker

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM