angularjs ng-click Как я могу использовать javascript setAttribute() для создания атрибута ng-click с некоторой функцией

Я хотел бы иметь возможность выбрать кнопку с помощью querySelector и установить атрибут "ng-click=doSomething()"

Я попытался выбрать кнопку, а затем setAttribute("ng-click", "doSomething()"), но она не работает

мой ДОМ:

<body>
    <div ng-app="myApp" ng-controller="mainCtrl">

        <button id="myBtn">click Me</button>

    </div>
    <script src="./js/app2.js"></script>
</body>

мой джаваскрипт:

(function() {
    "use strict";

    angular.module("myApp", []).controller("mainCtrl", mainCtrl);

    /** @ngInject */
    function mainCtrl($scope) {

      init();
      function init() {
          $scope.doSomething = () => {
              console.log("doing something");
          }
          let btn = document.querySelector('#myBtn');
          btn.setAttribute("ng-click", "doSomething()");
      }
    }
  })();

когда я нажимаю кнопку, он должен что-то регистрировать в консоли.


person Evan    schedule 21.05.2019    source источник
comment
Почему бы не использовать btn.addEventListener("click",$scope.doSomething)?   -  person georgeawg    schedule 21.05.2019
comment
можно ли добавить аргумент в doSomething, если я сделаю это таким образом?   -  person Evan    schedule 22.05.2019
comment
Да, это возможно, но я не буду писать ответ. В среде AngularJS контроллеры не должны выполнять манипуляции с DOM. Манипуляции с DOM должны выполняться только в директивах. Контроллеры должны только манипулировать моделью. Директивы соединяют модель с представлением и представление с контроллером. Переплетение ролей затрудняет понимание, тестирование, отладку и сопровождение кода. См. Не проектируйте свою страницу, а затем изменяйте ее с помощью манипуляций с DOM.   -  person georgeawg    schedule 22.05.2019
comment
в моем реальном проекте я использую компоненты, и я использую их в контроллере компонентов. приведенный выше код является всего лишь образцом.   -  person Evan    schedule 22.05.2019


Ответы (2)


(function() {
    "use strict";
        var btn = document.querySelector('#myBtn');
    btn.setAttribute("ng-click", "doSomething()");
    angular.module("myApp", []).controller("mainCtrl", mainCtrl);
        function mainCtrl($scope){
        $scope.doSomething = function(){
        alert('abc');
      }

    }
    angular.bootstrap(document, ['myApp']);         
})();

Пожалуйста, проверьте JSFiddle , разница в том, что вам нужно изменить html перед загрузкой angular, чтобы ваш измененный html и код js может быть правильно скомпилирован. Вот Руководство разработчика AngularJS — Bootstrap с дополнительной информацией о начальной загрузке angularjs.

person lucas    schedule 21.05.2019

Вообще говоря, если вы динамически добавляете "AngularJS-ified" в документ после его создания, например, динамически создаете <button> элементы, а затем добавляете к ним ng-click атрибуты, эти элементы не будут отслеживаться наблюдателями, и не быть частью нормального цикла пищеварения. Так, например, рассмотрим следующий простой пример:

const myApp = angular.module('stuff', [])
  .controller('stuff-cont', function($scope) {
    const targ = document.querySelector('#target');
    for (let i = 0; i < 10; i++) {
      let newBtn = document.createElement('button');
      newBtn.setAttribute('ng-click', 'sayRandNum()');
      newBtn.innerText = `Button ${i}`
      targ.append(newBtn);
    }
    $scope.sayRandNum = () =>{
      alert('Your random number is '+Math.ceil(Math.random()*100));
    }
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app='stuff' ng-controller='stuff-cont'>
  <div id='target'>
  </div>
  The buttons above are clickable, they have an appropriately "structured" ng-click, but they <i>don't trigger</i>!
</div>

Здесь мы (по какой-то причине...) создаем 10 почти идентичных кнопок. Однако из-за того, что когда мы создали эти ng-clickкнопки (а именно, после начальной фазы компиляции) и особенно когда мы добавили атрибуты ng-click (также после начальной фазы компиляции), кнопки фактически не «известен» циклу AngularJS».

С другой стороны, когда AngularJS впервые «загружается» на страницу, он сначала просматривает HTML на этой странице и ищет любые привязки данных ({{likeThis}}; мы их пока проигнорируем) или директивы. ng-click, ng-repeat и другие элементы Babbys First AngularJS представляют собой просто стандартизированные директивы, поэтому они являются частью этой процедуры "поиска директив". Когда AngularJS находит указанные директивы, он говорит: «Хорошо, у вас есть ng-click для этого элемента, я буду следить за этим».

Чтобы на самом деле добавить новые элементы, ориентированные на AngularJS, или добавить поведение AngularJS к существующим элементам, что, как я полагаю, больше относится к вам, вам нужно использовать функцию $compile, которая в основном говорит: «Эй, AngularJS! Я сделал новую вещь и хочу, чтобы вы его посмотрели!»

Этот ответ SO -- Работа с $compile в angularjs содержит довольно приличное объяснение того, как использовать функцию $compile.

person Newms    schedule 21.05.2019