louis w
louis w

Reputation: 127

Sharing data between directives using attributes instead of services

I wanted to make a directive that would essentially act like a specialized input field. After some logic & user input, the 'value' attribute would be populated with a string of comma separated timeslots (hh:mm).

<time-slot value=""></time-slot>

becomes

<time-slot value="01:00,02:00,03:00"></time-slot>

I'd like to provide the flexibility for anyone to place a scope reference in the 'value' attribute tag -- whenever the attribute value is updated, so is the scope reference. (In the code below, myModel.times would be in the MyController scope).

<div ng-controller="MyController">
  <time-slot value="{{ myModel.times }}"></time-slot>
</div>

I have had no problems accessing the 'value' attribute in the directive. However, I have not achieved two-way binding -- myModel.times never captures the changed value, even though the contents of the attribute have been changed when I inspect the element during runtime. I am using $attrs.$set to alter the value attribute.

I'm not sure if I'm missing something conceptually, or just missing some extra syntax. To keep this directive modular and shareable, I don't want to use a service to share data between the controller and directive, nor do I want to use a cascading scope. I think it would be optimal if the value attribute can simply be referenced by a scope variable and used as desired, much like a simple input tag:

<input ng-model="model.someText"></input>

Upvotes: 0

Views: 1208

Answers (1)

Esa Toivola
Esa Toivola

Reputation: 1538

An example with two-way data binding: See plunkr.

angular.module('myApp', [])
  .directive('timeSlots', function() {        
    return {
      scope: { value: '=' },          
      link: function($scope, $elem, $attrs) {
        // you can access $scope.value here (after it has been interpolated)
      }
    };  
  })
  .controller('MainCtrl', ['$scope', function($scope) {
    $scope.value = 42;
  }]);

In HTML:

<div ng-controller="MainCtrl">
  <time-slots value="value"></time-slots>      
</div>

Upvotes: 1

Related Questions