Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I've been working with AngularJS for a few days now, and I'm declaring two directives which work if I don't require anything. But I need the ngModel to use the $setViewValue method.

My directives look like this :

<corina>
    <properties data-ng-repeat="property in Properties"></properties>
</corina>

The directives are defined like :

var Application = Application || {};

;(function(window, document, undefined) {

    "use strict";

    var CorinaJSDialog = {};

    Application.CorinaJSDialog = angular.module("CorinaJSDialog", ["ngSanitize"]);

    Application.CorinaJSDialog.constant("CorinaJSAPI", {

        document : {
            load : "/corina/api/loaddocument",
            save : "/corina/api/savedocument"
        }
    });    

    Application.CorinaJSDialog.directive("corina", ["$timeout", function($timeout){

        var object = {

            restrict : "E",
            require : "ngModel",

            transclude : true,
            replace : true,
            priority : 1,
            templateUrl : "corina.html",
            controller : function($scope) {},
            link : function(scope, element, attrs, controller) { console.log(controller); }
        };

        return object;
    }]);

    Application.CorinaJSDialog.directive("properties", ["$timeout", function($timeout){

        var object = {

            restrict : "E",
            require : "?corina",
            transclude : true,
            replace : true,
            priority : 2,
            terminal : true,
            templateUrl : "properties.html",
            controller : function($scope) {},
            link : function(scope, element, attrs, controller) {

                var loadXeditable = function() {

                    $(element).editable({
                        mode: "inline",
                        display: function(value) {

                            controller.$setViewValue(value);

                            scope.$apply();

                            $(this).html(value);
                        }
                    });
                };

                $timeout(function() {
                    loadXeditable();
                }, 10);

            }
        };

        return object;
    }]);

})(window, document);

And the templates that are loaded :

corina.html :

<div>
    <div data-ng-transclude></div>
</div>

properties.html :

<div>
    <div class="row">
        <span class="span4">{{property.Name}}</span>

        <div class="span8">
            <a href="#" data-type="{{property.Type | lowercase}}" data-ng-model="property.Value" data-name="{{ property.Name }}" data-placeholder="{{ property.Value }}">
                <span data-ng-bind-html="{{ property.Value.toString() }}"></span>
            </a>
        </div>
    </div>
</div>

Each time I run the above I get this error :

Error: No controller: ngModel
at Error (<anonymous>)
at i (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js:41:165)
at l (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js:43:252)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js:47:425
at https://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js:96:330
at h (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js:78:207)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js:78:440
at Object.e.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js:89:272)
at Object.e.$digest (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js:87:124)
at Object.e.$apply (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js:89:431) <div data-ng-transclude=""> angular.min.js:62

Also, if I require the directive like ^mydir, I get the same error, or simply like mydir. Only if I use ?mydir I get no error, but then I cannot use ngModule directive. I would appreciate some input on what is it that I'm doing wrong.

share|improve this question
    
I believe that for a directive to be able to require: 'ngModel', ng-model="..." has to be used on the same element as the directive. –  Mark Rajcok Feb 26 '13 at 21:14
    
Ok, but even if I use it on the other directive where I have the ng-model I still get the same thing, and as I mentioned in the bottom of the post, if I require : "^mydir" or require : "mydir"I get the same error, only using require : "?mydir" works. There must be something in my code since on another project I have the same logic working just fine –  rolandjitsu Feb 26 '13 at 21:17

1 Answer 1

up vote 3 down vote accepted

As I interpret it, you have two element directives, corina and properties, where properties wants the controller from corina. That will always fail because because they need to be on the same element for require: 'corina' to work. But I see now in your template that properties are inside of corina, so what you should do in properties is this: require : "^?corina" instead. That tells Angular to look for the corina controller in parent elements as well.

Requiring ngModel in corina won't work though, since ng-model isn't set on the corina element. Your ng-model is set on an element inside the corina replacement template, so there's no way for the corina directive to get that ngModelController. You can only ask for controllers from the same element or from parent elements, not from child elements. If you really need ngModelController you should add your own directive on the same element that has ng-model and require ngModelController there. That directive can require the corina controller (since the corina controller is on a parent element) and pass the ngModelController to the corina controller.

But I'm not really sure why you want to use ng-model here in the first place? You've placed it on an anchor element which won't do anything. What is the effect that your after of having ng-model on an anchor element?

share|improve this answer
    
Thanks @AndersEkdhl :) The purpose of the ngModelController being there is that when I change the property.Value in one place I want to change it in other places too. It's hard to tell, but I'm using x-editable to edit inline and then save, so that a tag turns into a trigger for inline editing. I will try what you just proposed, I hope it works :) –  rolandjitsu Feb 27 '13 at 7:22
1  
Okey, so your anchor element turns into a form element by having a directive on type or any of the other attributes on your anchor? Then it makes sense, because ng-model only works for input, textarea and select. Placing it on any other element won't cause an error, but it won't do anything. –  Anders Ekdahl Feb 27 '13 at 7:27
    
do you see any errors here : snippi.com/s/rfke6qc ? I get an unexpected identifier on line 63 –  rolandjitsu Feb 27 '13 at 7:46
1  
You need to escape your quotes in template : "<a href=""></a>", like this: template : "<a href=\"\"></a>",. Or use single quotes, like this: template : '<a href=""></a>',. –  Anders Ekdahl Feb 27 '13 at 7:54
    
thanks @Anders :) –  rolandjitsu Feb 27 '13 at 7:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.