0

I am trying to build a custom directive for input box, which has input-model as an attribute used as ng-model. This input-model attribute is two way bound with an inner scope variable.

templateUrl:'/components/directives/inputBox.html',
transclude:true,
restrict: 'A',
scope:{
  userInput : '=inputModel'
}

Now the issue is, in the main html when I explicitly provide input-model, then it works fine. But I want a fallback when input-model is not provided, then the two way binding should be removed. The template is like

<input id="searchinput" type="search"
               name="inputBox"
               class="form-control"
               placeholder="{{placeholder}}"
               ng-model="userInput"
               ng-pattern="pattern"> 

So, when I do not provide the input-model attribute in the main html

<div input-box></div>

The binding fails as expected, giving the error :

Error: [$compile:nonassign] Expression 'undefined' used with directive 'inputBox' is non-assignable!

I want to make a fallback to avoid this scenario. How should I proceed?

2 Answers 2

1

Will this solution work for you?

Angular directive with default options

Sign up to request clarification or add additional context in comments.

Comments

1

You can check the defined attributes in the compile method, this will allow you to handle the case before binding takes place.

    return {
    template: '<div>{{userInput}} - test</div>',
    transclude: true,
    restrict: 'A',
    scope: {
        userInput: '=inputModel'
    },
    compile: function(element, attrs, transclude) {
        if (!attrs.inputModel) {
            attrs.inputModel = 'userInput';
        }
        return {
            pre: function(scope, element, attrs) {},
            post: function(scope, element, attrs) {}
        }
    }
};

http://jsfiddle.net/anf4ryzL/

5 Comments

Thanks! But have a question, if I use compile then I cant use link? then where to inject link function? in the post block?
Compile returns two methods, a pre-link and post-link these are your link functions. By default the link method used outside compile is the same as the post method so you can just use the post: function(){} in the same way as link
Ok. Then when to use the pre: function() {} block if I can handle pre-binding logic in compile itself?
The way compile works is in 3 steps, first angular runs a directives compile function, then it runs its own compile function which will set your isolated scope (this is why we set the attribute in the compile function first), then it passes the scope, element and attributes into a pre-link method and runs these in order of parent > child then it runs the post-link methods in reverse order child > parent. This means you can A. do stuff before angular makes your scope (compile), B. do stuff before all child directives links run (pre-link), C. do stuff after child directives links (post-link)
The difference between compile and pre-link/post-link is that compile has no scope yet, the isolated scope of your directive is created between compile and link

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.