0

I am trying to enhance our directive. It used to be one input type='submit' class="btn" element and the directive had replace: "true". I've changed the template for this directive to the following:

<input type="submit" value="{{value}}" id="btnChoose"
       ng-class="{{ngClass}}"
       style="width: 85% !important; margin-top: 0;"
       class="btn_file_select" ng-click="click()" />    

(Showing top part of HTML). I changed replace to false and added ngClass: '@' to the directive.

In my form I set ng-class to something and I can see it set when I inspect the element using Dev. Tools. I can also see that same ng-class expression added to my button. However, it doesn't work and it's not being evaluated.

How should I properly update my directive to be able to receive the ng-class property on the parent's div in the form and pass it to my button?

Sample of using this directive in a form right now:

<data-desc:type ng-class="{greenText: (currentSalespoint['lRemoteS' + n] == 0 && metaData.layOuts['dlrs' + n] > 0)}"
    title="{{ '@String.Format(Labels.selectX, Labels.printer)'}}"
    do-search="popup()"
    value="{{currentSalespoint['lRemoteS'+ n] == 0 ? (metaData.layOuts['dlrs' + n]==0?'@String.Format(Labels.selectX, Labels.printer)':metaData.layOuts['dlrs' + n + 'Text']) : currentSalespoint['lRemoteS'+ n + 'Text']}}"
    param="layouts"
    filter-by="Remote Printer"
    message="@String.Format(Labels.selectX, Labels.printer)"
    selected="currentSalespoint['lRemoteS'+ n]" descrip-value="descrip" type-value="'lRemoteS'+ n"
    description="currentSalespoint['lRemoteS'+ n 

    + 'Text']"></data-desc:type>

and the directive currently has the following at the top:

return {
            restrict: 'E',
            transclude: true,
            replace: false,

            scope: {
                title: '@',
                message: '@',
                param: '@',
                selected: '=',
                description: '=',
                value: '@',
                descrip: '=',
                type: '=',
                ngClass: '@',
                doSearch: '&',
                filterBy: '@?'
            },
2
  • 1
    Can you show a code sample of your directive? Commented Jul 25, 2017 at 21:10
  • I edited my current post to show sample of current usage. Commented Jul 25, 2017 at 21:21

1 Answer 1

2

Change the "@" to "=" and change ng-class="{{something}}" to ng-class="something", and don't use ngClass as the name of the scope property.

Embedding interpolated values inside of expressions is considered bad practice per this: https://docs.angularjs.org/guide/interpolation#known-issues

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

6 Comments

It means I would have to adjust all HTMLs that currently use this directive to use this new property, right? I was hoping for some way around. I'll try it since I think only 2 pages currently use ng-class with this directive
So, do I understand you correctly as you suggest, say, dynamicClass property. My directive will have dynamicClass: ='' and in the form I'll copy current ng-class to this dynamic-class and in the template for directive I'll have ng-class="dynamicClass" ?
If I understand your question correctly, then yes. You'll pass the expression through your directive's scope property bound as dynamicClass: '=' to the ng-class="dynamicClass" in its template. On the element that the directive is specified you'll also specify dynamic-class="expression". As long as it's a valid expression it should work. You can't use ngClass as the scope property because a directive with that name already exists.
While you were typing your comment I tried your suggestion and it worked. I now need to verify it works when I don't set this property in HTML.
If I don't set dynamic-class property then I get [Error: [$compile:nonassign] Expression 'undefined' in attribute 'dynamicClass' used with directive 'descType' is non-assignable!] I'll try dynamicClass: '=?' and see if it helps. UPDATE. It did help and now it works.
|

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.