{"_id":"56d91c5607ae190b00004471","__v":1,"version":{"_id":"56d91c5507ae190b00004460","__v":1,"project":"5515ba4981faf83900d2b10c","createdAt":"2016-03-04T05:25:41.052Z","releaseDate":"2016-03-04T05:25:41.052Z","categories":["56d91c5507ae190b00004464","56d91c5507ae190b00004465","56d91c5507ae190b00004466","56d91c5507ae190b00004467","56d91c5507ae190b00004468"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"8.0.0","version":"8.0.0"},"category":{"_id":"56d91c5507ae190b00004464","__v":1,"project":"5515ba4981faf83900d2b10c","pages":["56d91c5607ae190b00004469","56d91c5607ae190b0000446a","56d91c5607ae190b0000446b","56d91c5607ae190b0000446c","56d91c5607ae190b0000446d","56d91c5607ae190b0000446e","56d91c5607ae190b0000446f","56d91c5607ae190b00004470","56d91c5607ae190b00004471","56d91c5607ae190b00004472","56d91c5607ae190b00004473","56d91c5607ae190b00004474","56d91c5607ae190b00004475","56d91c5607ae190b00004476"],"version":"56d91c5507ae190b00004460","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-03-27T20:15:06.295Z","from_sync":false,"order":0,"slug":"guides","title":"Guides"},"project":"5515ba4981faf83900d2b10c","user":"54e3723b8ef7552300409bf4","updates":["5696bc968400d52d00dd5626"],"next":{"pages":[],"description":""},"createdAt":"2015-03-28T19:15:38.698Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":8,"body":"[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Complex, but powerful\",\n  \"body\": \"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.\"\n}\n[/block]\nThis is part of the built-in [formlyConfig](doc:formlyconfig) `templateManipulator` called `ngModelAttrsTemplateManipulator`. This allows you to keep your templates very small and add custom behavior on at the type or field level.\n\nThis api is a little complex. Hopefully these examples will be instructive.\n\nConfig like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  ngModelAttrs: {\\n    myCustomValue: {\\n      bound: 'ng-my-custom-value',\\n      attribute: 'my-custom-value'\\n    }\\n  },\\n  templateOptions: {\\n    myCustomValue: 3\\n  }\\n}\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nWould yield something like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<input ng-model=\\\"model[options.key]\\\" my-custom-value=\\\"3\\\" />\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nThe value is simply placed on the element using the attribute specified in `attribute`.\n\nWhereas if you changed the config to have an expressionProperty like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  ngModelAttrs: {\\n    myCustomValue: {\\n      bound: 'ng-my-custom-value',\\n      attribute: 'my-custom-value'\\n    }\\n  },\\n  templateOptions: {\\n    myCustomValue: 3\\n  },\\n  expressionProperties: {\\n    'templateOptions.myCustomValue': 'someEvaluationToGetCustomValue'\\n  }\\n}\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n\nThen the output would look like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<input ng-model=\\\"model[options.key]\\\" ng-my-custom-value=\\\"options.templateOptions['myCustomValue']\\\" />\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\n\nBecause the value of `templateOptions.myCustomValue` can change, it now uses the `bound` version of the attribute.\nHowever, if there is no `bound` version specified, but it is still an expression property like so:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  ngModelAttrs: {\\n    myCustomValue: {\\n      attribute: 'my-custom-value'\\n    }\\n  },\\n  templateOptions: {\\n    myCustomValue: 3\\n  },\\n  expressionProperties: {\\n    'templateOptions.myCustomValue': 'someEvaluationToGetCustomValue'\\n  }\\n}\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThen the output would look like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<input ng-model=\\\"model[options.key]\\\" my-custom-value=\\\"{{options.templateOptions['myCustomValue']}}\\\" />\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\n\nYou also have `expression`. For `expression` a config like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  ngModelAttrs: {\\n    doAction: {\\n      statement: 'do-something-awesome'\\n    }\\n  },\\n  templateOptions: {\\n    doAction: 'options.data.actionDone = true'\\n  }\\n}\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nWould result in output like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<input ng-model=\\\"model[options.key]\\\" do-something-awesome=\\\"$eval(options.templateOptions['doAction'])\\\" />\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nHowever, if the `templateOptions.doAction` is a function instead, like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  ngModelAttrs: {\\n    doAction: {\\n      statement: 'do-something-awesome'\\n    }\\n  },\\n  templateOptions: {\\n    doAction: function(value, options, scope, $event) {\\n      options.data.actionDone = true;\\n    }\\n  }\\n}\\n\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThen the output would look more like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<input ng-model=\\\"model[options.key]\\\" do-something-awesome=\\\"options.templateOptions['doAction'](model[options.key], options, this, $event)\\\" />\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nWhich allows you to have access to the `value`, `options`, `scope`, and `$event` as you see in the example.\n\nFinally, you can specify the custom attribute as a `value`. In this case, a config like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  ngModelAttrs: {\\n    '{{options.data.whatever}}': {\\n      value: 'my-whatever-attribute'\\n    }\\n  }\\n}\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nWould give you this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<input ng-model=\\\"model[options.key]\\\" my-whatever-attribute=\\\"{{options.data.whatever}}\\\" />\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nWhich gives you the liberty to specify exactly the value you wish for your attribute in the template.\n[block:html]\n{\n  \"html\": \"<hr />\\n<a href=\\\"https://app.codesponsor.io/link/PKGFLnhDiFvsUA5P4kAXfiPs/formly-js/angular-formly\\\" rel=\\\"nofollow\\\"><img src=\\\"https://app.codesponsor.io/embed/PKGFLnhDiFvsUA5P4kAXfiPs/formly-js/angular-formly.svg\\\" style=\\\"width: 888px; height: 68px;\\\" alt=\\\"Sponsor\\\" /></a>\\n\"\n}\n[/block]","excerpt":"Complex but powerful field api","slug":"ngmodelattrs","type":"basic","title":"ngModelAttrs"}

ngModelAttrs

Complex but powerful field api

[block:callout] { "type": "info", "title": "Complex, but powerful", "body": "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." } [/block] This is part of the built-in [formlyConfig](doc: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: [block:code] { "codes": [ { "code": "{\n ngModelAttrs: {\n myCustomValue: {\n bound: 'ng-my-custom-value',\n attribute: 'my-custom-value'\n }\n },\n templateOptions: {\n myCustomValue: 3\n }\n}", "language": "javascript" } ] } [/block] Would yield something like this: [block:code] { "codes": [ { "code": "<input ng-model=\"model[options.key]\" my-custom-value=\"3\" />", "language": "html" } ] } [/block] 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: [block:code] { "codes": [ { "code": "{\n ngModelAttrs: {\n myCustomValue: {\n bound: 'ng-my-custom-value',\n attribute: 'my-custom-value'\n }\n },\n templateOptions: {\n myCustomValue: 3\n },\n expressionProperties: {\n 'templateOptions.myCustomValue': 'someEvaluationToGetCustomValue'\n }\n}", "language": "javascript" } ] } [/block] Then the output would look like this: [block:code] { "codes": [ { "code": "<input ng-model=\"model[options.key]\" ng-my-custom-value=\"options.templateOptions['myCustomValue']\" />", "language": "html" } ] } [/block] 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: [block:code] { "codes": [ { "code": "{\n ngModelAttrs: {\n myCustomValue: {\n attribute: 'my-custom-value'\n }\n },\n templateOptions: {\n myCustomValue: 3\n },\n expressionProperties: {\n 'templateOptions.myCustomValue': 'someEvaluationToGetCustomValue'\n }\n}", "language": "javascript" } ] } [/block] Then the output would look like this: [block:code] { "codes": [ { "code": "<input ng-model=\"model[options.key]\" my-custom-value=\"{{options.templateOptions['myCustomValue']}}\" />", "language": "html" } ] } [/block] You also have `expression`. For `expression` a config like this: [block:code] { "codes": [ { "code": "{\n ngModelAttrs: {\n doAction: {\n statement: 'do-something-awesome'\n }\n },\n templateOptions: {\n doAction: 'options.data.actionDone = true'\n }\n}", "language": "javascript" } ] } [/block] Would result in output like this: [block:code] { "codes": [ { "code": "<input ng-model=\"model[options.key]\" do-something-awesome=\"$eval(options.templateOptions['doAction'])\" />", "language": "html" } ] } [/block] However, if the `templateOptions.doAction` is a function instead, like this: [block:code] { "codes": [ { "code": "{\n ngModelAttrs: {\n doAction: {\n statement: 'do-something-awesome'\n }\n },\n templateOptions: {\n doAction: function(value, options, scope, $event) {\n options.data.actionDone = true;\n }\n }\n}\n", "language": "javascript" } ] } [/block] Then the output would look more like this: [block:code] { "codes": [ { "code": "<input ng-model=\"model[options.key]\" do-something-awesome=\"options.templateOptions['doAction'](model[options.key], options, this, $event)\" />", "language": "html" } ] } [/block] 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: [block:code] { "codes": [ { "code": "{\n ngModelAttrs: {\n '{{options.data.whatever}}': {\n value: 'my-whatever-attribute'\n }\n }\n}", "language": "javascript" } ] } [/block] Would give you this: [block:code] { "codes": [ { "code": "<input ng-model=\"model[options.key]\" my-whatever-attribute=\"{{options.data.whatever}}\" />", "language": "html" } ] } [/block] Which gives you the liberty to specify exactly the value you wish for your attribute in the template. [block:html] { "html": "<hr />\n<a href=\"https://app.codesponsor.io/link/PKGFLnhDiFvsUA5P4kAXfiPs/formly-js/angular-formly\" rel=\"nofollow\"><img src=\"https://app.codesponsor.io/embed/PKGFLnhDiFvsUA5P4kAXfiPs/formly-js/angular-formly.svg\" style=\"width: 888px; height: 68px;\" alt=\"Sponsor\" /></a>\n" } [/block]