AngularJS - динамическое манипулирование DOM без жесткого кодирования dom id в контроллере

Я все еще начинаю работать с angular, и кажется, что «подход Angular» заключается в том, чтобы отделить представление от контроллера, и поэтому мои манипуляции с DOM в angular пока кажутся очень неуклюжими. так как мне нужно много вручную выбирать элемент dom. В настоящее время мое приложение выглядит примерно так:

HTML:

<div ng-controller="appController as appCtrl">
    <div>
        <div id="element1"></div>
        <div id="element2"></div>
        <div id="element3"></div>
        <button ng-click="appCtrl.animateStuff()"></button>
    </div>
</div>

КОНТРОЛЛЕР:

app.controller('appController', ['animationFactory', 'domFactory', appControllerFunc]);
function appControllerFunc(animationFactory, domFactory) {
    This = this;
    This.animateStuff = function() {
        animationFactory.animate(domFactory.getNgElementById('element1'));
        animationFactory.animate(domFactory.getNgElementById('element2'));
        animationFactory.animate(domFactory.getNgElementById('element3'));
    }
}

ЗАВОДЫ:

app.factory('domFactory', [domFactoryFunc]);
function domFactoryFunc() {
    var domFactoryContainer = {
        getNgElementById: function(id) {
            return angular.element(document.getELementById(id));
        }
    }
    return domFactoryContainer;
}

app.factory('animationFactory');
function animationFactoryFunc() {
    var animationFactoryContainer = {
        animate: function(ngelement) {
            // animates ngelement
        }
    }
    return animationFactoryContainer;
}

Есть ли способ как-то отправить элементы DOM в контроллер из ng-click представления? Что-то вроде ngclick = "ctrl.animateStuff ([# element1], [# element2], [# element3])", поэтому моему контроллеру просто нужно получить параметры и управлять ими, даже не зная ничего о DOM? Или для этого можно использовать директивы? если да, то как?


person sgarcia.dev    schedule 18.12.2014    source источник
comment
Вы правы - подход Angular состоит в том, чтобы отделить представление от контроллера, поэтому НЕ делайте никаких предположений (например, идентификаторов элементов) о DOM в контроллере. Другими словами, если вы чувствуете, что вам нужно получить доступ к DOM из контроллера, вы делаете это неправильно.   -  person New Dev    schedule 19.12.2014
comment
Добавил дополнительную информацию к моему вопросу, извините, кажется, он был отключен, когда я его записал и скопировал-вставил из блокнота   -  person sgarcia.dev    schedule 19.12.2014
comment
Прочтите, как делать анимацию в Angular с помощью ngAnimate. Он использует элемент, но его нет в контроллере.   -  person New Dev    schedule 19.12.2014
comment
Я использую свою собственную настраиваемую библиотеку анимации с использованием GSAP, поскольку я создаю первое мобильное приложение, похожее на нативное, которое использует сложные анимации с аппаратным ускорением, поэтому мне нужна эта библиотека.   -  person sgarcia.dev    schedule 19.12.2014


Ответы (2)


Если вы не можете использовать Angular ngAminate (который не требует манипуляций с DOM, поскольку он использует css), вы можете создать собственный директива. Директивы - это то место, где разрешены манипуляции с DOM, и вы получите фактический элемент, переданный в директиву, поэтому нет необходимости в жестко заданных идентификаторах.

Но я рекомендую следовать предложению @ NewDev.

Это была бы возможная заглушка для директивы:

module.directive('myAnimation', function() {
  return {
    restrict: 'A',
    scope: {
      enabled: '='
    },
    link: function(scope, element) {
      // watch on enabled and start animation when set to true
    }
  }
});

И ваша разметка:

<div my-animation enabled='enabled'></div>
<div my-animation enabled='enabled'></div>
<div my-animation enabled='enabled'></div>
<button ng-click="enabled=true"></button>
person orange    schedule 19.12.2014

Чтобы разблокировать вас прямо сейчас, вы могли бы сделать

<div id="element1" ng-click="ctrl.animateStuff($event)"></div>    

который передаст событие вашей функции, и вы сможете извлечь из нее элемент DOM.

Я не знаком с GSAP, но вы сможете подключить его к ngAnimate-способу работы.

И, повторюсь - НЕ обращайтесь к DOM в вашем контроллере и не делайте никаких предположений о нем - вы нарушаете лучшие практики Angular и часто сталкиваетесь с проблемами и головными болями.

person New Dev    schedule 19.12.2014
comment
Если не в контроллере, где я должен манипулировать DOM? Кроме того, я раньше использовал параметр $ event, проблема в том, что мне не нужно получать вызывающий элемент, мне нужно несколько элементов рядом с ним (которые, как я знаю, я могу получить, используя closest () с вызывающим элементом, но который по-прежнему требует жесткого кодирования идентификатора DOM) - person sgarcia.dev; 19.12.2014
comment
Прочтите о ngAnimate - именно здесь происходит манипулирование DOM, связанное с анимацией. - person New Dev; 19.12.2014