Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - Input change outside directive value passed in to directive

I am a beginner to AngularJs and I cannot figure out how to retrieve data from outside a directive. I have various input being updated and I need the directive to take this data and work with it.

For example, in the code below, the first input field is hooked up to the directive and works fine, but without putting the directive attribute on the second input field, how can the data typed in that field be updated in the directive?

HTML:

<div ng-app="myDirective">
    <input type="text" ng-model="test1" my-directive>
    <input type="text" ng-model="test2">
</div>

Directive:

angular.module('myDirective', [])
    .directive('myDirective', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            scope.$watch(attrs.ngModel, function (v) {
                console.log('New Value from field 1: ' + v);
                //console.log('New Value from field 2: ' + ???);
            });
        }
    };
});
like image 636
Aaron Avatar asked May 22 '13 15:05

Aaron


2 Answers

I could have explained that in text, but I think it would be much better if you watch these 3 videos by john lindquist:

  • Isolate Scope "@"
  • Isolate Scope "="
  • Isolate Scope "&"

And summary.

They are really short (~4min each) but very simple and useful.

PS: by the way, i recommend you to watch others as well. They are all short and precise, loved them.

like image 109
Artur Udod Avatar answered Dec 28 '22 13:12

Artur Udod


Since your directive does not create a new scope, the scope variable inside the directive's link method points to the outer scope containing the two inputs. So you can replace:

//console.log('New Value from field 2: ' + ???);

with

console.log('New Value from field 2: ' + scope.test2);

Make sure to enter some data in the second input when testing or it will print undefined.

Here is a working fiddle


EDIT: If you did need to use isolate scope in your directive, you could do the following in your HTML:

<input type="text" ng-model="test1" my-directive="test2">
<input type="text" ng-model="test2">

The difference here is now passing in the test2 model into the directive, and setting up a binding to it in your directive by adding the scope property:

scope: {
    otherInput: '=myDirective'
    // this tells the directive to bind the local variable `otherInput`
    // to whatever the `my-directive` attribute value is. In this case, `test2`
},

This allows you to access passed values in your directive. You would then change your $watches as follows:

scope.$watch(attrs.ngModel, function (v) {
    console.log('New Value from field 1: ' + v);
    console.log('New Value from field 2: ' + scope.otherInput);
});

// notice the syntax for watching a scope variable
scope.$watch('otherInput', function (v) {
    console.log('New Value from field 1: ' + scope.test1);
    console.log('New Value from field 2: ' + v);
});

I've included this in my fiddle as another example, test3 and test4.

like image 39
Dan Avatar answered Dec 28 '22 15:12

Dan