Guides
GuidesExamplesGitterLog In
Guides

ngModelAttrs

Complex but powerful field api

📘

Complex, but powerful

The API for this is a bit complex, but predictable, and quite powerful. If you simply want to put an attribute on your ng-model element, look into the ngModelElAttrs property.

This is part of the built-in formlyConfig templateManipulator called ngModelAttrsTemplateManipulator. This allows you to keep your templates very small and add custom behavior on at the type or field level.

This api is a little complex. Hopefully these examples will be instructive.

Config like this:

{
  ngModelAttrs: {
    myCustomValue: {
      bound: 'ng-my-custom-value',
      attribute: 'my-custom-value'
    }
  },
  templateOptions: {
    myCustomValue: 3
  }
}

Would yield something like this:

<input ng-model="model[options.key]" my-custom-value="3" />

The value is simply placed on the element using the attribute specified in attribute.

Whereas if you changed the config to have an expressionProperty like this:

{
  ngModelAttrs: {
    myCustomValue: {
      bound: 'ng-my-custom-value',
      attribute: 'my-custom-value'
    }
  },
  templateOptions: {
    myCustomValue: 3
  },
  expressionProperties: {
    'templateOptions.myCustomValue': 'someEvaluationToGetCustomValue'
  }
}

Then the output would look like this:

<input ng-model="model[options.key]" ng-my-custom-value="options.templateOptions['myCustomValue']" />

Because the value of templateOptions.myCustomValue can change, it now uses the bound version of the attribute.
However, if there is no bound version specified, but it is still an expression property like so:

{
  ngModelAttrs: {
    myCustomValue: {
      attribute: 'my-custom-value'
    }
  },
  templateOptions: {
    myCustomValue: 3
  },
  expressionProperties: {
    'templateOptions.myCustomValue': 'someEvaluationToGetCustomValue'
  }
}

Then the output would look like this:

<input ng-model="model[options.key]" my-custom-value="{{options.templateOptions['myCustomValue']}}" />

You also have expression. For expression a config like this:

{
  ngModelAttrs: {
    doAction: {
      statement: 'do-something-awesome'
    }
  },
  templateOptions: {
    doAction: 'options.data.actionDone = true'
  }
}

Would result in output like this:

<input ng-model="model[options.key]" do-something-awesome="$eval(options.templateOptions['doAction'])" />

However, if the templateOptions.doAction is a function instead, like this:

{
  ngModelAttrs: {
    doAction: {
      statement: 'do-something-awesome'
    }
  },
  templateOptions: {
    doAction: function(value, options, scope, $event) {
      options.data.actionDone = true;
    }
  }
}

Then the output would look more like this:

<input ng-model="model[options.key]" do-something-awesome="options.templateOptions['doAction'](model[options.key], options, this, $event)" />

Which allows you to have access to the value, options, scope, and $event as you see in the example.

Finally, you can specify the custom attribute as a value. In this case, a config like this:

{
  ngModelAttrs: {
    '{{options.data.whatever}}': {
      value: 'my-whatever-attribute'
    }
  }
}

Would give you this:

<input ng-model="model[options.key]" my-whatever-attribute="{{options.data.whatever}}" />

Which gives you the liberty to specify exactly the value you wish for your attribute in the template.


Sponsor