1

Am creating a custom directive which takes a simple template consist of input type textarea am assigning the ng-model to ngmodel and creating a link function in this am creating a on change event where am trying to get the ngmodel value but its printing undefined, please help me to resolve this issue, here by posting the link which I have tried do corrections if required plunkr ,code starts here

// Code goes here

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

app.directive('markdownEditor', function () {
  return {
    restrict: 'E',
    scope: {
      ngModel: "="
    },
    require:'ngModel', 
    template:
    '<textarea ng-model="ngModel"></textarea>' +
    '{{ ngModel}}',
    link:function(scope,ele,attr,ctrl){
      ele.on("keydown",function(){
        alert(scope.ctrl)
      })
    }
  }
});

app.controller('DemoCtrl', function ($scope) {
  var x= $scope.markdown;
});
<html ng-app="myApp">
  <body>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
    <div ng-controller="DemoCtrl">
      <h3>Markdown editor</h3>
      <markdown-editor ng-model="markdown" name="markdown"></markdown-editor>
    </div>
  </body>
</html>
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
balajivaishnav
  • 2,795
  • 4
  • 23
  • 38
  • try referencing the model controller as `ctrl` instead of `scope.ctrl` – paul trone Feb 02 '16 at 16:30
  • change `scope.ctrl` to `scope.ngModel` and change `keydown` to `keyup`. – Sumit Sahay Feb 02 '16 at 16:55
  • Err you not binding to `scope.ctrl` in your `ngModel`. Also be aware you may have to call `$apply` if you wish to make scope changes in your event handler. That is happening outside of angulars scope. – ste2425 Feb 02 '16 at 16:58

2 Answers2

0

At least two things are going wrong here: you're trying to alert the controller itself, instead of the ng-model variable, and checking on keydown means you'll always be one keystroke behind.

Try this instead:

var app = angular.module('myApp', []);
app.directive('markdownEditor', function() {
    return {
        restrict: 'E',
        require: 'ngModel',
        template: '<textarea ng-model="foo"></textarea>',
         link: function(scope, ele, attr, ctrl) {
            ele.on("keyup", function() { // (or use "change" if you don't need to check every single keystroke)
                alert(scope.foo);
            })
        }
    }
});

app.controller('DemoCtrl', function($scope) {
});

https://plnkr.co/edit/wf0NBnQqmgcwE606xeZg

(I would strongly suggest against naming your variable "ngModel" -- it's super confusing as it makes it difficult to distinguish between the variable and the ngModel directive itself.)

Daniel Beck
  • 20,653
  • 5
  • 38
  • 53
  • if I want to get the ngmodel at run time means what should I do have any idea – balajivaishnav Feb 02 '16 at 17:21
  • I don't understand what you mean by "get the ngmodel at runtime" -- can you clarify what you're trying to do? – Daniel Beck Feb 02 '16 at 17:28
  • actually I want to create a directive which automatically takes the ngmodel value when using that directive in html for ex – balajivaishnav Feb 02 '16 at 17:53
  • Still not quite following. Are you trying to use a dynamic variable name for your ng-model? If so see http://stackoverflow.com/questions/12553617/how-can-i-set-a-dynamic-model-name-in-angularjs – Daniel Beck Feb 02 '16 at 18:15
  • yep I need to give a dynamic ngmodel variable name and I have to access in my custom directive – balajivaishnav Feb 02 '16 at 18:24
  • Yes, see the answers in the link I gave above, http://stackoverflow.com/questions/12553617/how-can-i-set-a-dynamic-model-name-in-angularjs – Daniel Beck Feb 03 '16 at 04:16
  • I didn't found any thing what am looking for in that link which you gave,they did not use any directives as such I do – balajivaishnav Feb 03 '16 at 04:30
  • I think maybe at this point you might be better off reviewing some ng-model tutorials, it doesn't seem that continuing like this is going to help you. – Daniel Beck Feb 03 '16 at 04:39
  • Thanks for your reply, is on keyup event is good for writing validation because the error is showing too late to but working fine in console log have any suggestion on that – balajivaishnav Feb 03 '16 at 13:10
  • If you're validating a text input, `keyup` will give you whatever the user just entered. `keydown` will give you the text *before* the most recent change (much less useful). `change` will trigger only when the field blurs. If you're using keyup you'll want to debounce the input (see `ng-model-options`). This is all wandering quite far from the original question, if you need continued help please post a new question focused on that particular issue. – Daniel Beck Feb 03 '16 at 13:24
0

You need to add the name of scope property like:

alert(scope.ngModel)

PS: PLEASE AVOID USING ngModel as VARIABLE NAME

// Code goes here

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

app.directive('markdownEditor', function () {
  return {
    restrict: 'E',
    scope: {
      ngModel: "="
    },
    require:'ngModel', 
    template:
    '<textarea ng-model="ngModel"></textarea>' +
    '{{ ngModel}}',
    link:function(scope,ele,attr,ctrl){
      ele.on("keyup",function(){
        alert(scope.ngModel)
      })
    }
  }
});

app.controller('DemoCtrl', function ($scope) {
  var x= $scope.markdown;
});
<html ng-app="myApp">

<body>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
  <div ng-controller="DemoCtrl">
    <h3>Markdown editor</h3>
    <markdown-editor ng-model="markdown" name="markdown"></markdown-editor>
  </div>
</body>

</html>
Alvaro Silvino
  • 9,441
  • 12
  • 52
  • 80