JiniKJohny
JiniKJohny

Reputation: 1182

Isolate scope in reusable angular direcives

I have a custom directive : myContent

'use strict';

angular.module('myModule').directive('myContent', function() {
  return {
    restrict: 'E',
    templateUrl: 'myContent.html',

    controller: function($scope){
      $scope.selectedContents = {
        priceOrTransactionOption : null,
        yearlyOrMonthly : 'Yearly',
        contentIndicator : null
      };
      $scope.comboContent = {
        priceOrTransactionOption : ['By Price Range', 'By Transactions'],
        yearlyOrMonthly : ['Yearly', 'Monthly'],
        contentIndicator : ['Active configuration', 'Next Configuration']
      };
    },
    controllerAs: 'myContentCtrl'
  };
});

And I'm using this same directive in multiple places :

<div class="tab-content col-lg-10">
      <my-content></my-content>
</div>

<div class="tab-content col-lg-10">
     <my-content></my-content>
</div>

<div class="tab-content col-lg-10">
     <my-content></my-content>
</div>

And my html page for the directive (myContent.html) is having some data with :

<div class="row no-left-padding">
    <div class="col-lg-3 no-left-padding">
        <select class="form-control" ng-model="selectedContent.priceOrTransactionOption"
                ng-options="keyOption as keyOption for keyOption in comboContent.priceOrTransactionOption">
        </select>
    </div>
    <div class="col-lg-3 no-left-padding">
        <select class="form-control" ng-model="selectedContent.yearlyOrMonthly" ng-disabled = "true"
                ng-options="interval as interval for interval in comboContent.yearlyOrMonthly">
        </select>
    </div>

    <div class="col-lg-3 no-left-padding">
        <select class="form-control" ng-model="selectedContent.contentIndicator"
                ng-options="indicator as indicator for indicator in comboContent.contentIndicator">
        </select>
    </div>
</div>

But my problem is, when ever I'm changing the model in one directive, it reflects in each directives.

How can I use the same directive, and map each with different models?

I had tried with wadding one attribute to my custom directive:

<div class="tab-content col-lg-10">
      <my-content category="type1"></my-content>
</div>

<div class="tab-content col-lg-10">
     <my-content category="type2"></my-content>
</div>

<div class="tab-content col-lg-10">
     <my-content category="type3"></my-content>
</div>

But still I'm confused with where should I map the category for getting isolated object.

Upvotes: 4

Views: 62

Answers (3)

Claies
Claies

Reputation: 22323

It appears what you want is to return selectedContents for each instance of the directive. To do this, you would use angular two way binding to create a link between your directive and the page content.

angular.module('myModule').directive('myContent', function() {
  return {
    restrict: 'E',
    templateUrl: 'myContent.html',
    scope: {
      selectedContents: '='  
    },
    controller: function($scope){
      $scope.selectedContents = {
        priceOrTransactionOption : null,
        yearlyOrMonthly : 'Yearly',
        contentIndicator : null
      };
....

now, you can refer to the selectedContents as a parameter on the directive.

<div class="tab-content col-lg-10">
      <my-content selectedContents="someObject.selectedContents"></my-content>
</div>
<div class="tab-content col-lg-10">
      <my-content selectedContents="someOtherObject.selectedContents"></my-content>
</div>

Upvotes: 1

sarin
sarin

Reputation: 5307

You need to add Isolated scope to your directive. This effectively allows it to have its own set of properties:

angular.module('myModule').directive('myContent', function() {
  return {
    restrict: 'E',
    templateUrl: 'myContent.html',
    scope: { 
         category:'='
    },
    controller: function($scope){
      $scope.selectedContents = {
        priceOrTransactionOption : null,
        yearlyOrMonthly : 'Yearly',
        contentIndicator : null
      };
      $scope.comboContent = {
        priceOrTransactionOption : ['By Price Range', 'By Transactions'],
        yearlyOrMonthly : ['Yearly', 'Monthly'],
        contentIndicator : ['Active configuration', 'Next Configuration']
      };
    },
    controllerAs: 'myContentCtrl'
  };
});

You can then use your example above:

<div class="tab-content col-lg-10">
      <my-content category="type1"></my-content>
</div>

And each one will work individually.

Take note though, when you add your properties of the isolated scope binding '='. There are a number of different types, '@', '=' and '&' as well as optional arguments. The naming of your scope property uses snake case. Rather than me giving you a full explanation, read the Angular developers guide on isolated scope

Upvotes: 4

Sidharth Panwar
Sidharth Panwar

Reputation: 4654

Try adding this in your directive definition:

restrict: 'E',
scope: {},

Upvotes: 1

Related Questions