Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get ng-model value inside custom directive

I've searched here on SO and tried the answers I found, but I can't seem to get the model value out of the ngModel of my custom directive.

enter image description here

Here's the directive

/*
 *usage: <markdown ng:model="someModel.content"></markdown>
 */
breathingRoom.directive('markdown', function () {
    var nextId = 0;
    return {
        require: 'ngModel',
        replace: true,
        restrict: 'E',
        template: '<div class="pagedown-bootstrap-editor"></div>',
        link:function (scope, element, attrs, ngModel) {

            var editorUniqueId = nextId++;
            element.html($('<div>' +
                '<div class="wmd-panel">' +
                '<div id="wmd-button-bar-' + editorUniqueId + '"></div>' +
                '<textarea class="wmd-input" id="wmd-input-' + editorUniqueId + '">{{modelValue()}}' +
                '</textarea>' +
                '</div>' +
                '<div id="wmd-preview-' + editorUniqueId + '" class="wmd-panel wmd-preview"></div>' +
                '</div>'));

            var converter = new Markdown.Converter();

            var help = function () {
                // 2DO: add nice modal dialog
                alert("Do you need help?");
            };

            var editor = new Markdown.Editor(converter, "-" + editorUniqueId, {
                handler: help
            });

            editor.run();


            // local -> parent scope change (model)
            jQuery("#wmd-input-" + editorUniqueId).on('change', function () {
                var rawContent = $(this).val();
                ngModel.$setViewValue(rawContent);
                scope.$apply();
            });

            // parent scope -> local change
            scope.modelValue = function () {
                console.log('modelvalue - ', ngModel.$viewValue);
                return ngModel.$viewValue;
            };
        }
    };
});

And here's the HTML

<markdown ng-class="{error: (moduleForm.Description.$dirty && moduleForm.Description.$invalid) || (moduleForm.Description.$invalid && submitted)}"
          id="Description" 
          name="Description" 
          placeholder="Description" 
          ng-model="module.description" 
          required></markdown>   

The problem here is that the output is simply

{{modelValue()}}

I also tried creating a private method

function getModelValue() {
    console.log(ngModel.$viewValue);
    return ngModel.$viewValue;
}

and then change the one template line to

'<textarea class="wmd-input" id="wmd-input-' + editorUniqueId + '">' + getModelValue() +

but then the output is

NaN

Where am I going wrong?


if it matters, here's the order of my scripts (not including vendor scripts)

<script src="app.js"></script>
<script src="directives/backButtonDirective.js"></script>
<script src="directives/bootstrapSwitchDirective.js"></script>
<script src="directives/markdownDirective.js"></script>
<script src="directives/trackActiveDirective.js"></script>
<script src="services/alertService.js"></script>
<script src="services/roleService.js"></script>
<script src="services/moduleService.js"></script>
<script src="services/changePasswordService.js"></script>
<script src="services/userService.js"></script>
<script src="controllers/usersController.js"></script>
<script src="controllers/userController.js"></script>
<script src="controllers/moduleController.js"></script>
<script src="controllers/modulesController.js"></script>
like image 623
Chase Florell Avatar asked Mar 06 '14 22:03

Chase Florell


People also ask

What is [( ngModel )]?

The ngModel directive is a directive that is used to bind the values of the HTML controls (input, select, and textarea) or any custom form controls, and stores the required user value in a variable and we can use that variable whenever we require that value. It also is used during form validations.

How do you change the value of an NG-model?

If we use two way binding syntax for ngModel the value will be updated. So the default (ngModelChange) function will update the value of ngModel property. i.e., user.Name . And the second (ngModelChange) will be triggered printing the user name value in the console.

What is the use of NG-model directive?

The ng-model directive binds the value of HTML controls (input, select, textarea) to application data.


1 Answers

The HTML your inserting isn't getting compiled. It's easiest just to move it into your template, or investigate using ng-transclude. Here's an example of moving it into your template.

plunker

breathingRoom.directive('markdown', function () {
    var nextId = 0;
    return {
        require: 'ngModel',
        replace: true,
        restrict: 'E',
        template: '<div class="pagedown-bootstrap-editor"><div class="wmd-panel">' +
                '<div id="wmd-button-bar-{{editorUniqueId}}"></div>' +
                '<textarea class="wmd-input" id="wmd-input-{{editorUniqueId}}">{{modelValue()}}' +
                '</textarea>' +
                '</div>' +
                '<div id="wmd-preview-{{editorUniqueId}}" class="wmd-panel wmd-preview"></div>' +
                '</div></div>',
        link:function (scope, element, attrs, ngModel) {

            scope.editorUniqueId = nextId++;

            // parent scope -> local change
            scope.modelValue = function () {
                console.log('modelvalue - ' + ngModel.$viewValue);
                return ngModel.$viewValue;
            };
        }
    };
});
like image 129
Craig Squire Avatar answered Oct 13 '22 01:10

Craig Squire