Как динамически добавить директиву [ngStyle] в ionic 3 / angular

Это то, что у меня было, и он работал, он был привязан к методу progress и отображался правильно:

<div [ngStyle] = "{'width.%': progress()}"></div>

Теперь мне нужно создать элемент динамически:

let myDiv = <HTMLElement>(document.createElement('div'));

но я не могу найти способ привязать метод прогресса к моему динамически создаваемому элементу.

Код с использованием рендерер, предложенный @fatemefazli, который не имеет обнаружения изменений, поэтому он не отображает, когда данные становятся доступными, и не прослушивает изменение метода выполнения: https://stackblitz.com/edit/angular-fpyfmn

Решение создавать элементы DOM динамически исходит из необходимости присоединить жест панорамирования с помощью HammerJS, который требует присоединить слушателя следующим образом:

addGestures(elem){
    var hammer = new Gesture(elem);
    hammer.listen();

    hammer.on('pan', (e) => this.Pan(e));
  }

Я попытался создать публикующий / эмиттер события, но у меня нет триггера для его публикации.

Не прямой ответ, но разве вы не можете добиться того же, используя *ngIf вместо динамического создания элемента?

Ari 04.06.2018 23:51

Я реализовал это с помощью шаблона, как вы говорите, но новые требования / реализация требуют динамического создания элемента, я знаю, что это звучит немного слишком сложно из-за отсутствия информации об общей картине, но это единственный вариант, который у меня есть сейчас. Спасибо за комментарий.

August 05.06.2018 14:23

angular имеет встроенную поддержку жестов от hammerjs: material.angular.io/guide/…, и даже если этого не произошло, нет необходимости создавать элемент динамически. Вы можете просто получить ссылку на элемент из шаблона и добавить к нему жест в компоненте.

Poul Kruijt 13.06.2018 09:52
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
9
3
3 221
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

constructor(public el: ElementRef, public renderer: Renderer){
    this.myDiv = <HTMLElement>(document.createElement('div'));
    renderer.setElementStyle(this.myDiv , 'width', this.progress()+'%');
}

Спасибо, попробовал, но выдает ошибку о том, что данные, которые используются в процессе, не определены при рендеринге шаблона. Первоначально он отображал Can not find "renderer", и я использовал его как this.render.setElementStyle ....

August 04.06.2018 21:51

После обхода и добавления его только после того, как данные будут доступны, я получаю: TypeError: undefined не является объектом (оценка 'el.style')

August 04.06.2018 22:00

@ Август, пожалуйста, опубликуйте свой полный код или прогресс? Я пробовал, этот код работал в простом состоянии, возможно, ваш другой.

Fateme Fazli 04.06.2018 22:03

Хотя это может дать ответ на вопрос, лучше включить некоторое описание того, как этот ответ помогает решить проблему. Пожалуйста, прочтите Как мне написать хороший ответ?.

Narendra Jadhav 05.06.2018 08:09

Я думаю, что проблема возникает из-за разницы между директивой style (используемой в этом ответе), которая является директивой HTML, привязанной к значению, и NgStyle (используемой в моей предыдущей реализации), которая является директивой Angular, которая «слушает» наличие данные с течением времени.

August 05.06.2018 14:49

Реализовано, но не делает того же, что и NgStyle: не отображается, когда значения становятся доступными, и значение не обновляется постоянно, как при использовании с NgStyle. См. Мой предыдущий комментарий.

August 05.06.2018 21:45

@ Август, может быть, вы правы, я сделал stackblitz, проверьте его в консоли и внесите ваши изменения, мне было бы полезно понять,

Fateme Fazli 05.06.2018 22:25

@fatemefazli Спасибо за попытку помочь, вот случай получше: stackblitz.com/edit/angular-fpyfmn?embed=1&file=app/…

August 05.06.2018 23:05

@August, да, теперь я понимаю, вы правы, я не смог найти способ динамически изменять стиль, способ - установить функцию ElementStyle в процессе выполнения, когда вы хотите ее обновить. спасибо за хороший вопрос.

Fateme Fazli 06.06.2018 00:21

@fatemefazli Благодарю вас за попытку помочь, ваше решение - верный аргумент, но не в моем случае.

August 06.06.2018 03:26

Вы не должны самостоятельно обрабатывать изменение DOM (и добавление элемента).

Даже при использовании средства визуализации этого следует избегать.

Я бы посоветовал использовать привязку событий и данных к жестко запрограммированному элементу, как вы это сделали в первый раз.

И если вам действительно нужно создать div по каким-либо причинам, тогда, пожалуйста, объясните нам, чего вы хотите достичь, потому что, вероятно, для вас есть решение, которое не связано с самим прикосновением к DOM.

Ответ принят как подходящий

Как сказал TricheTriche, вы не должны напрямую обращаться к DOM. Фактически, это не только не рекомендуется, но и не будет работать для динамических изменений, поскольку на самом деле это больше не выполняется внутри угловой зоны.

Что вам нужно сделать:

  1. создайте новый заполнитель в вашем текущем компоненте, который будет размещать (2)
  2. создать новую директиву, отвечающую за прослушивание и обработку событий, а также за рендеринг любых изменений стиля
  3. используйте ComponentFactoryResolver для динамического внедрения (2) в (1)

Ознакомьтесь с более подробной информацией на странице Angular Страница загрузки динамических компонентов Angular, на которой они представляют работающий пример чего-то похожего на то, что вам нужно.

Другие вопросы по теме