Question

I am trying to create a ui that is generated using a schema object containing properties and validation etc. I need to set ngModel on my ui controls using a directive as a result. The value of ngModel is a string which represents a property path on a schema object on the scope.

I have this working for standard inputs, but when using angular ui datepicker i get the following error.

Error: [$compile:ctreq] Controller 'ngModel', required by directive 'myModel', can't be found!
http://errors.angularjs.org/1.2.10/$compile/ctreq?p0=ngModel&p1=myModel
at http://localhost:3000/javascripts/angular.js:78:20
at getControllers (http://localhost:3000/javascripts/angular.js:6054:39)
at nodeLinkFn (http://localhost:3000/javascripts/angular.js:6225:55)
at compositeLinkFn (http://localhost:3000/javascripts/angular.js:5634:37)
at compositeLinkFn (http://localhost:3000/javascripts/angular.js:5637:33)
at compositeLinkFn (http://localhost:3000/javascripts/angular.js:5637:33)
at publicLinkFn (http://localhost:3000/javascripts/angular.js:5539:46)
at boundTranscludeFn (http://localhost:3000/javascripts/angular.js:5653:37)
at controllersBoundTransclude (http://localhost:3000/javascripts/angular.js:6245:36)
at Object.ngIfWatchAction [as fn] (http://localhost:3000/javascripts/angular.js:18316:29)

<input class="form-control" datepicker-popup="dd-MMM-yyyy" my-model="" is open="property.calOpen" close-text="Close" ng-model="editModel.Person.Detail.DateOfBirth">

The directive I have is below.

angular.module('MyDirectives',[])
.directive('myModel', function($compile , $timeout) {
    return {
        restrict: 'A',                       
        priority:0,

        link: function(scope,element, attr) {

            if(angular.isDefined(attr.ngModel))return;
            var field = scope.path ? scope.path + '.' + scope.key : scope.key;
            attr.$set("ngModel", "editModel." + field);

            console.log("in directive");
            $timeout(function(){
                $compile(element)(scope);
            });
        }
    };

As the value for ngModel lives on the scope, I believe I need the link function rather than compile. I have tried adding Require: ?ngModel to the directive which makes no difference. Also tried increasing priority, but this changes error to Error: [$compile:ctreq] Controller 'ngModel', required by directive 'input', can't be found!

If I remove the $timeout(function(){} surrounding $compile(element)(scope) 2 popup calendars appear overlayed. This is noticable when navigating through months.

Any Ideas

UPDATE: see link plkr

Was it helpful?

Solution

You need to create a new two-way binding to a local scope variable (scope: true).
Use $parse to locate the property at the path.

See updated Plunker

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top