title: Angularjs: custom two-way binding attribute directive
body: <p>I have to write a directive that would have the following behavior :</p>
  
  <p>Controller:</p>
  
  <pre><code>vm.mymodel = 'Hello World'
  </code></pre>
  
  <p>Html:</p>
  
  <pre><code>&lt;custom-input mydirective="{propbind: 'data-value', propmodel: vm.mymodel}"&gt;&lt;/custom-input&gt;
  </code></pre>
  
  <p>I would like my custom-input to be transformed as follow:</p>
  
  <pre><code>&lt;custom-input data-value="{{vm.mymodel}}"&gt;&lt;/custom-input&gt;
  </code></pre>
  
  <ul>
  <li>When I update vm.mymodel from the controller, the data-value attribute has to change.</li>
  <li>When I update the data-value, the vm.mymodel has to be updated too.</li>
  <li>I can't use ng-mmodel directive on the custom-input (it uses data-value, and has internal functions applied to it)</li>
  </ul>
  
  <p>So here's what I tried to do :</p>
  
  <ul>
  <li>In the compile function of my directive, set scope.propbind attribute value to "{{propmodel}}", then remove "mydirective" attribute. But I don't seem to have access to the scope here. However, if I use element.attr('data-value', 'hello world') I can see my data-value correctly set</li>
  <li>I tried to do the same in the link function, but my scope's values are undefined</li>
  <li>I also tried in the controller function, but my scope is also empty, plus I don't have access to attr or element.</li>
  </ul>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var app = angular.module('myApp', []);
  app.controller('myctrl', function($scope) {
    var vm = this;
    this.mymodel = 'Hello world !';
  });
  
  app.directive('mydirective', function () {
        return {
          restrict: 'A',
          replace: false,
          transclude: false,
          scope: {
            bindingvalue: '='
          },
          compile: function(element) {
            //remove the element for clarity
            element.removeAttr('mydirective'); 
          },
          link: function($scope, elem, attr) {
            //set the attribute
            attr.$set($scope.bindingvalue.propbind, $scope.bindingvalue.propmodel);
            //Observe the attribute value for changes
            attr.$observe($scope.bindingvalue.propbind, function(value) {
              $scope.bindingvalue.propmodel = value;
            })
          },
          controller: function($scope, $element) {
            //Nothing here yet
          }
        }
      });</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"&gt;&lt;/script&gt;
  
  &lt;div ng-app="myApp" ng-controller="myctrl as vm"&gt;
    &lt;input mydirective="{propbind: 'data-value', propmodel: vm.mymodel}" type="text"/&gt;
    model value : {{vm.mymodel}}
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Can you please help me ? Is my logic good for my problem ? I think that if I manage to get my scope values in my link function, everythink could work.</p>
  
  <p>Thanks</p>