Angular — невозможно получить доступ к методам контроллера после компиляции директивы

Я сильно модифицирую плагин WYSIWYG js и вставляю в него свои собственные пользовательские элементы. Чтобы вставить пользовательские элементы, я использую директивы, чтобы их можно было легко поддерживать, если мне нужно внести изменения. Вот пример моего кода:

Первоначальная загрузка редактора wysiwyg:

<div ng-controller="wyswiygCtrl">
    <textarea wysiwyg-editor ng-model="content"></textarea>
</div>

Вот пример пользовательского элемента (директивы), который я вставляю в содержимое wysiwyg:

<wysiwyg-element class="custom_element" name="awesome" type="checkbox" checked="true"></wysiwyg-element>

Я использую следующий код в рамках инициализации директивы для компиляции любых пользовательских элементов (директив) внутри него:

var e = angular.element(wysiwygEditor.get(0).innerHTML);
$compile(e.contents())(scope);
wysiwygEditor.html(e);

Он компилирует директивы именно так, как мне нужно, но здесь начинается сложная часть. Мне нужно иметь возможность вызывать функцию в «wysiwygCtrl» из OUTSIDE angular. Я могу сделать это перед компиляцией, но по какой-то причине после использования функции компиляции angular я не могу получить доступ к области действия элементов.

Вот код, который работает до $compile:

angular.element($('.custom_element')).scope().wysiwygModal();
angular.element($('.custom_element')).scope().$apply();

Я получаю следующую ошибку после попытки вызвать функцию wysiwygModal после компиляции $:

Uncaught TypeError: Object #<Object> has no method 'wysiwygModal'

Что я делаю не так?


person Sneaksta    schedule 30.10.2013    source источник


Ответы (1)


Я смог получить доступ к scope() и его переменным в скомпилированном элементе. Не могли бы вы отредактировать этот plunkr или создать свой собственный, если это не поможет?

http://plnkr.co/edit/kvbvKXeVjEhmeE7257ly?p=preview

script.js

var myApp = angular.module('myApp', []);

myApp.directive('myEditor', function () {
  return {
    restrict: 'E',
    scope: {
    },
    template: 
      '<div>' + 
        '<h3>Raw HTML</h3>' + 
          '<textarea rows=5 cols=40 ng-model="text"></textarea>' + 
        '</div>' + 
        '<hr />' +
        '<div>' + 
          '<h3>Compiled HTML</h3>' + 
          '<div my-preview></div>' + 
        '</div>' +  
        '<hr />' +
        '<div>' + 
          '<h3>Messages generated during compilation</h3>' + 
          '<div ng-repeat="message in messages">[{{message}}]</div>' + 
        '</div>' + 

      '</div>',
    controller: function ($scope) {
      $scope.messages = [];

      this.getText = function () {
        return $scope.text;
      };

      this.addMessage = function (message) {
        $scope.messages.push(message);
      };

      this.clearMessages = function () {
        $scope.messages.length = 0;
      };
    },
    link: function (scope, element, attrs) {
      scope.text = '<div ng-init="a = 2" class="my-selector">\n    scope.a : [{{a}}]\n</div>';
    }
  };
});

myApp.directive('myPreview', function ($compile) {
  return {
    require: '^myEditor',
    link: function (scope, element, attrs, myEditorController) {
      scope.$watch(myEditorController.getText, function (newValue) {
        if (newValue !== undefined) {
          var e = angular.element('<div>' + newValue + '</div>');
          $compile(e)(scope);
          element.html(e);

          myEditorController.addMessage(
            'The value of "a" on the scope of the compiled element is: ' + 
            angular.element($('.my-selector')).scope().a)
        }
      });
    }    
  };
});

index.html

<!DOCTYPE html>
<html>

  <head>
    <script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
    <script data-require="angular.js@*" data-semver="1.2.0-rc3-nonmin" src="http://code.angularjs.org/1.2.0-rc.3/angular.js"></script>

    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <div ng-app="myApp">
      <my-editor></my-editor>
    </div>
  </body>

</html>
person Jesus is Lord    schedule 31.10.2013