3

mydirective is an isolated scope directive. This is because I don't want to expose all the logical of the directive to anywhere outside of the directive. But I want to access the input data, outside of the directive.

<div mydirective>
   <input ng-model="data.input">
</div>

<div mydirective>
   <input ng-model="otherdata.public">
   <input ng-model="more.than.one">
</div>

{{data.input}}
{{otherdata.public}}

I prefer that the HTML will work without changing it , and change ONLY the directive code. So I want to know how to create the directive

app.directive('mydirective',function(){ return {
 scope:true,
 controller:function($scope){
     $scope.this_variable_needs_to_be_private=true
 },
 transclude:true
}})

EDIT: add transclude:true. But still I have no answer for the question.

Aminadav Glickshtein
  • 23,232
  • 12
  • 77
  • 117
  • 1
    Do you mean `transclude:true`:[https://docs.angularjs.org/api/ng/directive/ngTransclude]? – Joy Jul 22 '15 at 09:30
  • Yes. I mean to transclude:true – Aminadav Glickshtein Jul 22 '15 at 10:04
  • 1
    You can use a service that contains the variables, and inject this service in directive or controller. – mggSoft Jul 22 '15 at 11:04
  • @mggSoft. Thank you. Can you give me more information about it? – Aminadav Glickshtein Jul 22 '15 at 11:51
  • 1
    There is already information on the subject here: http://stackoverflow.com/questions/31100796/sharing-services-variables-across-controllers-angular-ionic OR http://stackoverflow.com/questions/18196802/angular-share-asynchronous-service-data-between-controllers – mggSoft Jul 22 '15 at 12:06
  • 1
    I leave my response to a old post (with an example): http://stackoverflow.com/questions/30975516/passing-updating-data-in-a-factory-from-one-controller-to-another/30975802#30975802 – mggSoft Jul 22 '15 at 12:17
  • @mggSoft , In the question you mention he asked that "all referencing the same object inside the same factory with the hope that if I set it to some other value". But I want to create new reference to the factory on each controller. Is it possibile? – Aminadav Glickshtein Jul 22 '15 at 12:27
  • Services are singleton, so you have one reference, but you can inject it in each controller. – mggSoft Jul 22 '15 at 12:31

2 Answers2

2

Consider using the $transclude function along with creating your own childScope with $scope.$new():

(function() {
  "use strict";

  angular.module("myApp", [])
    .controller("Controller1", ['$scope', Controller1])
    .directive("mydirective", [mydirective]);

  function Controller1($scope) {
    $scope.data = {
      input: 'data.input'
    };
    $scope.otherdata = {
      public: 'otherdata.public'
    };
    $scope.more = {
      than: {
        one: 'more.than.one'
      }
    }
  }

  function mydirective() {
    function _link($scope, $element, $attrs, controller, $transclude) {
      var childScope = $scope.$new(); //create a childScope

      //$scope.this_variable_needs_to_be_private = true; //<-- doing this would add it to public parent scope
      childScope.this_variable_needs_to_be_private = true; //<-- this puts it only on this directive's childscope

      // See: https://docs.angularjs.org/api/ng/service/$compile#transclusion
      $transclude(childScope, function(clone, scope) { //transcluding with our childScope
        $element.append(clone); //appending the clone of our content;
      });
    }

    return {
      transclude: true,
      link: _link
    };
  }

})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
<div ng-app="myApp" ng-controller="Controller1">

  <div mydirective>
    <input ng-model="data.input">
    <br /><strong>this_variable_needs_to_be_private:</strong> {{this_variable_needs_to_be_private}}
  </div>

  <br />

  <div mydirective>
    <input ng-model="otherdata.public">
    <input ng-model="more.than.one">
    <br /><strong>this_variable_needs_to_be_private:</strong> {{this_variable_needs_to_be_private}}
  </div>

  <hr />
  <strong>data.input:</strong> {{data.input}}
  <br /><strong>otherdata.public:</strong> {{otherdata.public}}
  <br /><strong>this_variable_needs_to_be_private:</strong> {{this_variable_needs_to_be_private}}


</div>

Further reading on $transclude: https://stackoverflow.com/a/13184889/446030.

Community
  • 1
  • 1
JcT
  • 3,539
  • 1
  • 24
  • 34
  • 1
    Awesome. This is what I forgot to use: "var childScope = $scope.$new()". Exactly what I want. Now the directive can access public scope, and private scope! – Aminadav Glickshtein Jul 22 '15 at 13:08
  • 1
    No worries! The angular source has some interesting examples within. The above is to some extent a super-simplification of what ngRepeat does (minus the expression parsing and repetition!). – JcT Jul 22 '15 at 13:12
  • btw. How you include runnable snippet inside? (It's plunkr), but for me it is only links... – Aminadav Glickshtein Jul 22 '15 at 13:14
  • The question/answer editor has a button for inserting code snippets, separate from the inline code markup one. – JcT Jul 22 '15 at 13:17
-1

To access the directive's isolated scope variables, either you can use one-way or two-way data bindings like below:

app.directive('mydirective',function(){ return {
 scope:{var1:"=outerVar"},
 controller:function($scope){
     $scope.var1='I am accessible outside...';
 }
}})

Child scope's variables will not be visible anyhow in parent. You need to use parent scope's variables in isolated scope to communicate between them.

mjaydip
  • 143
  • 1
  • 8