Использование угловой двусторонней привязки с собственным веб-компонентом
Итак, у меня есть собственный веб-компонент, который я хочу использовать с Angular. Но я не хочу добавлять какой-либо угловой код в нативный компонент, так как я также хочу использовать его с другими фреймворками и с сырым JS.
Это работает нормально, пока я не попытаюсь получить двустороннюю привязку к работе.
Согласно Angular Docs мне нужно только отправить событие с названием свойства +"Изменить". Например, в моем угловом шаблоне:
<my-el ([value])="angularVariable"></my-el>
Что я ожидаю от вышеизложенного, так это то, что когда angularVariable
изменено, то измененное значение передается свойству value
из my-el
, И это, когда мой элемент отправляет событие valueChange
что-то, что я посылаю с этим событием, должно быть установлено в переменную angularVariable
,
Углубившись в код Angular, похоже, это будет работать, только если я использую Angular. EventEmitter
и не традиционные события DOM.
Я могу сделать следующее, и это прекрасно работает:
<my-el [value]="angularVariable" (valueChange)="angularVariable = $event.detail"></my-el>
В этом случае я отправляю событие из моего веб-компонента следующим образом:
this.dispatchEvent(new CustomEvent('valueChange', { bubbles: true, detail: value }));
Кто-нибудь знает, что я могу сделать, чтобы заставить это работать в двухсторонней связующей манере?
ОБНОВЛЕНИЕ - Для уточнения:
Веб-компонент должен оставаться Собственным веб-компонентом без каких-либо требований к какой-либо среде.
Я надеюсь, что Angular предоставит стандарт, который, если его придерживаться, позволит компоненту играть в мире двухстороннего связывания.
Вот пример компонента:
const elTag = 'my-el-2';
const styles = document.createElement('style');
styles.setAttribute('component', elTag);
styles.textContent = `
${elTag} {
background: white;
border: 1px solid #555;
display: block;
}
${elTag} > div {
background-color: #F00;
height: 20px;
}
`;
document.body.append(styles);
// ------------------ Start of Custom Element ------------------
class MyEl2 extends HTMLElement {
static get observedAttributes() {
return ['percent'];
}
constructor() {
super();
this._percentEl = document.createElement('div');
this.percent = 0;
}
connectedCallback() {
this.appendChild(this._percentEl);
}
disconnectedCallback() {
this.removeChild(this._percentEl);
}
attributeChangedCallback(attrName, oldVal, newVal) {
if (oldVal !== newVal) {
this[attrName] = parseFloat(newVal);
}
}
get percent() {
return this._percent;
}
set percent(value) {
// Keep value within the range of 0 and 100;
value = (value < 0) ? 0 : (value > 100) ? 100 : value;
if (this._percent !== value) {
this._percent = value;
this._percentEl.style.width = `${value}%`;
if(value > 0) {
this.setAttribute('percent', value);
}
else {
this.removeAttribute('percent');
}
this.dispatchEvent(new CustomEvent('percentChange', { bubbles: true, detail: value }));
}
}
}
customElements.define(elTag, MyEl2);
// ------------------ End of Custom Element ------------------
var bdec = document.querySelector('#dec');
var binc = document.querySelector('#inc');
var myEl = document.querySelector('my-el-2');
bdec.addEventListener('click', ()=>{
myEl.percent--;
});
binc.addEventListener('click', ()=>{
myEl.percent++;
});
<my-el-2 percent="35"></my-el-2>
<button id="dec">-</button>
<button id="inc">+</button>
С этим элементом, который является 100% -ным ванилью, я надеялся отправить определенное событие, которое позволило бы двухсторонней привязке Angular работать. В этом случае именно эта строка:
this.dispatchEvent(new CustomEvent('percentChange', { bubbles: true, detail: value }));