3

I want to pass object (reference - two way binding) through ATTRIBUTE not by isolated scope. How can I do this? Because code bellow passing string instead of object:

HTML

<tr ng-form="rowForm" myDirective="{{row.data}}">

Directive

angular.module("app").directive("myDirective", function () {
    return {
        require: ["^form"],
        restrict: "A",
        link: function (scope, element, attrs, ctrls) {
            scope.$watch(function () {
                return attrs.myDirective;
            }, function (newValue, oldValue) {
            // .....

3 Answers 3

5

Directives can do two-way data binding without parsing or compile anything manually, sorry for not delivering the plunker but it's rebelius and won't save for me

JS

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.myObj = {name: 'Tibro', age: 255}
})
.directive('myDirective', function(){
  return {
    scope: {
      'myAttribute': '='
    },
    template: '{{myAttribute}}',
    link: function(scope){
      scope.myAttribute.age= 31
    }
  }
})

HTML

  <body ng-controller="MainCtrl">
    controller: {{myObj}} <br/>
    directive: <my-directive my-attribute="myObj"></my-directive>
  </body>

OUTPUT

controller: {"name":"Tibro","age":31} 
directive: {"name":"Tibro","age":31}

you can see from the output that passed object has been binded two-way and change made in directive is reflected on controller level

Sign up to request clarification or add additional context in comments.

5 Comments

Let's say I will deal with a isolate scope. In directive in part "link: {...}" I have a function scope.doSomthing. How can I run this function in html (ng-click) if scope is isolated?
is the doSomething in the scope of directive or controller, what's your use case?
Here: link: function(scope){ scope.doSomething = function() {...} } And I want to call it in html by ng-click="doSomething()". Before I added isolated scope: { } to directive, everything was working
You can still do it template: '<button ng-click="doSomething()">do smth</button>'
I have this button in HTML file, not in directive. And if i click on it, then nothing happens
2

The result of {{ }} interpolation is a string. An object can't be passed like that.

Bindings are idiomatic here and thus preferable. The whole thing becomes messy when the directive is forced to use parent scope. However, it can be done by parsing scope properties manually with $parse:

  $scope.$watch(function () {
    var myDirectiveGetter = $parse($attrs.myDirective);
    return myDirectiveGetter($scope);
  }, ...);

This is a job for binding (< or =, depending on the case). If isolated scope isn't desirable, this can be done with inherited scope and bindToController:

scope: true,
bindToController: {
  myDirective: '<'
},
controllerAs: `vm`,
controller: function ($scope) {
  $scope.$watch('vm.myDirective', ...);
}

Notice that directive attribute is my-directive, not myDirective.

Comments

0

Couple of things:

  1. myDirective in the tr should be my-directive, as per Angular's conventions.
  2. {{row.data}} prints the variable, you need to pass it without the {{}} for it to go through as an object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.