Search code examples
javascriptangularjsangularjs-directiveangular-directive

To pass an interpolated expression into an Angular Directive


I have seen this question asked few times. But not able to implement the solution mention in those answer in the right way. I am new to Angular and trying to use Observe or watch to pass interpolated expressions into a custom directive to obtain a one way binding.

I am not sure what is the correct way to use $observe to attain this behavior.

I tried this.

attr.$observe('oneway', function (attributeValue) {
                    scope.oneway = scope.$parent.$eval(attributeValue);
                });

But found the following issues

  1. value in the attribute must not contain {{}} else $eval will fail. <mydir oneway=Prop1></mydir> will work

    `<mydir oneway={{Prop1}}></mydir>` fails
    
     But this will fail my entire objective to  have a one-way binding
    between directive and parent       
    
  2. Even if I have an expression inside the directive, $observe get fired only once. Changing the {{Prop1}} doesn't fire the observe function.

  3. I tried using $watch instead of $observe. But still facing the same issue

What is the correct way to use observe\watch to obtain a one-way binding between controller and directive ?

Following the complete code

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>TestView</title>
    <script src="~/Scripts/angular.js"></script>
    <script>
        function customdir1() {
            var directiveDefinitionObject = {};
            directiveDefinitionObject.templateUrl = "/CustomControl/HtmlPage1.html";
            directiveDefinitionObject.scope = { oneway: "@@oneway" };
            directiveDefinitionObject.link = function (scope, element, attr, ctrl) {


                attr.$observe('oneway', function (attributeValue) {

                    scope.oneway = scope.$parent.$eval("Prop1");
                });


            }
            return directiveDefinitionObject;
        }

        var app = angular.module("myapp", []).controller("myCont", function ($scope) {
            $scope.Prop1 = "TestProp1Text";

        }).directive("mydir", customdir1);
    </script>
</head>
<body ng-app="myapp">
    <div ng-controller="myCont">
        {{Prop1}}
        <input type="text" ng-model="Prop1" />
        <mydir oneway={{Prop1}}></mydir>
    </div>
</body>
</html>

Markup in the Template (HtmlPage1.html)

<b>HII</b>
  {{oneway}}
<input type="text" ng-model="oneway" />

Thanks So much in Advance..


Solution

  • Here is a fiddle of what you need. https://jsfiddle.net/Tsalikidis/eg93q1rc/

    <mydir oneway="foo"></mydir>
    

    and just use '=' to directive's scope

    ...
    scope: {
      oneway: '='
    }