{"id":15661306,"url":"https://github.com/jameshenry/ng-custom-element","last_synced_at":"2025-04-26T18:55:39.378Z","repository":{"id":33256067,"uuid":"147242448","full_name":"JamesHenry/ng-custom-element","owner":"JamesHenry","description":":sparkles: Legacy AngularJS (1.3+) bindings to modern Custom Elements","archived":false,"fork":false,"pushed_at":"2022-12-08T18:36:59.000Z","size":2463,"stargazers_count":19,"open_issues_count":23,"forks_count":6,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-30T08:25:22.409Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://jameshenry.blog","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JamesHenry.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-03T18:55:38.000Z","updated_at":"2023-07-25T00:26:26.000Z","dependencies_parsed_at":"2023-01-15T00:16:04.797Z","dependency_job_id":null,"html_url":"https://github.com/JamesHenry/ng-custom-element","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JamesHenry%2Fng-custom-element","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JamesHenry%2Fng-custom-element/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JamesHenry%2Fng-custom-element/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JamesHenry%2Fng-custom-element/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JamesHenry","download_url":"https://codeload.github.com/JamesHenry/ng-custom-element/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250864387,"owners_count":21499666,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T13:26:58.411Z","updated_at":"2025-04-25T17:44:20.579Z","avatar_url":"https://github.com/JamesHenry.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eng-custom-element\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003eLegacy AngularJS bindings to modern Custom Elements\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://travis-ci.org/JamesHenry/ng-custom-element\"\u003e\u003cimg src=\"https://img.shields.io/travis/JamesHenry/ng-custom-element.svg?style=flat-square\" alt=\"Travis\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/JamesHenry/ng-custom-element/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/ng-custom-element.svg?style=flat-square\" alt=\"GitHub license\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/ng-custom-element\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/ng-custom-element.svg?style=flat-square\" alt=\"NPM Version\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/ng-custom-element\"\u003e\u003cimg src=\"https://img.shields.io/npm/dt/ng-custom-element.svg?style=flat-square\" alt=\"NPM Downloads\" /\u003e\u003c/a\u003e\n    \u003ca href=\"http://commitizen.github.io/cz-cli/\"\u003e\u003cimg src=\"https://img.shields.io/badge/commitizen-friendly-brightgreen.svg\" alt=\"Commitizen friendly\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/semantic-release/semantic-release\"\u003e\u003cimg src=\"https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square\" alt=\"semantic-release\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n## Background\n\nCustom elements are great. Angular Elements is a great way of making custom elements from Angular code. Angular Elements is therefore also a great upgrade strategy for AngularJS apps looking to upgrade to Angular.\n\nIn AngularJS 1.7.3, some helpers were introduced for binding properties and events to custom elements from surrounding AngularJS code.\n\nFor example:\n\n```js\nangular.module('app', ['']).controller('ExampleController', function() {\n  this.controllerProp = {\n    somObj: 'val'\n  };\n  this.onClick = function clickHandler($event) {\n    console.log('was clicked', $event);\n  };\n});\n```\n\n```html\n\u003cmy-element ng-prop-my_prop=\"$ctrl.controllerProp\" ng-on-click=\"$ctrl.onClick($event)\"\u003e\u003c/my-element\u003e\n```\n\n## ng-prop-\\* and ng-on-\\* are awesome, but not backwards compatible\n\nThe changes introduced to facilitate the helpers for ng-prop-\\* and ng-on-\\* are not backwards compatible. This library therefore exposes a custom directive called `ng-custom-element` which allows you to emulate how it works!\n\nIt has been tested in AngularJS versions as far back as 1.3, but it may even work in versions older than that.\n\nAssuming the exact controller code from above, let's compare the HTML from the AngularJS 1.7.3+ helpers and this library:\n\n**AngularJS 1.7.3+**\n\n```html\n\u003cmy-element ng-prop-my_prop=\"$ctrl.controllerProp\" ng-on-click=\"$ctrl.onClick($event)\"\u003e\u003c/my-element\u003e\n```\n\n**ng-custom-element (AngularJS 1.3+)**\n\n```html\n\u003cmy-element ng-custom-element ngce-prop-my_prop=\"$ctrl.controllerProp\" ngce-on-click=\"$ctrl.onClick($event)\"\u003e\u003c/my-element\u003e\n```\n\nPretty sweet!\n\n## Usage\n\n1. Install the library and add its angular.module as a dependency of your own:\n\n```js\nangular.module('yourAwesomeApp', ['ngCustomElement']);\n```\n\n2. Apply the attribute directive `ng-custom-element` to any DOM element you want to bind properties or events to\n\n```html\n\u003cmy-element ng-custom-element\u003e\u003c/my-element\u003e\n```\n\n3. Use `ngce-prop-*` to bind properties (**see the notes on casing below**) to the element:\n\n```html\n\u003cmy-element ng-custom-element ngce-prop-my_prop=\"someAngularJSControllerProp\"\u003e\u003c/my-element\u003e\n```\n\n4. Use `ngce-event-*` to bind events (**see the notes on casing below**) to the element:\n\n```html\n\u003cmy-element ng-custom-element ngce-on-click=\"someAngularJSControllerMethod($event)\"\u003e\u003c/my-element\u003e\n```\n\n## Notes on casing\n\nWe need to pay special attention to casing.\n\n**From the ngProp docs**: https://docs.angularjs.org/api/ng/directive/ngProp\n\n\u003e Since HTML attributes are case-insensitive, camelCase properties like innerHTML must be escaped. AngularJS uses the underscore (_) in front of a character to indicate that it is uppercase, so innerHTML must be written as ng-prop-inner_h_t_m_l=\"expression\" (Note that this is just an example, and for binding HTML ngBindHtml should be used).\n\n**From the ngOn docs**: https://docs.angularjs.org/api/ng/directive/ngOn\n\n\u003e Since HTML attributes are case-insensitive, camelCase properties like myEvent must be escaped. AngularJS uses the underscore (_) in front of a character to indicate that it is uppercase, so myEvent must be written as ng-on-my_event=\"expression\".\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjameshenry%2Fng-custom-element","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjameshenry%2Fng-custom-element","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjameshenry%2Fng-custom-element/lists"}