0

Using my custom directive I would like to move the ng-model from root directive to child input element. For some reason the model is not working on child element. Here is the code

Markup:

<span usinglink ng-model="test">
      <input type="checkbox"  value="test" />
      <span>{{test}}</span>
    </span>

Directive:

mymodule.directive('usinglink', function($compile){
        return{
          link : function(scope, element, attrs){
               element.children('input').attr('ng-model',element.attr('ng-model'));    
          }
        } 
     });

This exact thing works when I use compile instead of link. Can anyone tell the reason for this behavior and way i can achieve this behavior using link.

omwmodule.directive('prNgDropdown', function ($compile) {
        return {
            compile : function (element, attributes) {
                var selectElement = element;
                if (element.attr("ng-model") != undefined) {
                             element.attr("ng-init", element.attr("ng-model") + "= '" + element.val() + "'");
                }
                //'Removing the directive after the logic.as  the custom directive is placed on the same element. compile would create an infinit loop

                //selectElement.removeAttr("pr-ng-dropdown");
                //$compile(selectElement.parent())(scope);

            }
        }
    });

For some reason my ng-init is not updating the model.Can you please explain what was missing.

3
  • works for me even without $compile. I can see ng-model added to input tag. What is you angular version? Mine is 1.3.13 Commented Apr 1, 2015 at 1:00
  • how can you say that ng-model is working. when the check box is checked/unchecked. Is the model changing? Commented Apr 1, 2015 at 3:57
  • sorry :-( but would have been much better if you had been more explicit in the problem statement itself. "not working" is often not sufficiently clear jimho... Commented Apr 1, 2015 at 4:55

1 Answer 1

1

Manually writting HTML (which is what element.attr(val) does) will not be processed by Angular. For it to be processed and updated, an HTML need to be compiled by Angular, which is what happens when you put this code in the compile phase.

If you want that to work in the link phase, you will need to manually compile the resulting HTML so all the watchers are set and the bindings are bound.

var input = element.children('input'); 
input.attr('ng-model',element.attr('ng-model'));
$compile( input )($scope);
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you. Its working now. can you please explain me why it worked for compile function without doing anything.
No problem. That's because that's the whole point of the compile phase: you generate some HTML based on whatever the attributes and bindings are, and that HTML will be compiled and then processed by angular during the link phase. In fact, it would make more sense for your directive to have this code in the compile phase.
Thats true. but I have an additional logic where I have to watch for this model.Based on the model value I need to add a css class. Please let me know If I didn't explain you clearly.
Nothing prevent you to first compile that input in the compile phase, and then do the watchers and logic in the link phase (you can have both of course). For instance if you need to add a class you put it in scope.myclass in the link phase, and in the compile phase you generate <div ng-class="myclass">. But it's ok to do everything in the link if you feel it's simpler.
hi I just updated the question. can you please let me know why my ng-model is not being updated with ng-init.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.