可以将一个指令$编译器注入服​​务吗?

时间:2016-03-15 04:54:42

标签: angularjs angularjs-directive angularjs-service angularjs-controller angularjs-injector

我尝试将directive输出为javascript string,以便将html放在代码显示窗口中。我对实际代码而不是浏览器呈现版本感兴趣,因为我向高级用户显示代码。所以我希望能够将指令函数注入服务或页面控制器。

这与使用$compile或甚至$interpolate类似,但对于特定指令。我认为我已经定义了该指令,我可以以某种方式访问​​html生成函数。我知道您可以在指令定义中定义控制器,但我正在寻找我在服务或页面控制器中使用的解决方案。

因此,作为一个例子,假设我在模块中定义了一个指令

mod.directive("superThing", function() {
        return {
            templateUrl: "/superThing.html",
            scope: {
               variableA: "="
            }
        };
    });

前服务:

 mod.service("applicationService", [ "$rootScope", "superThing",
        function ($rootScope, superThing) {
          $rootScope.result = superThing($rootScope);
       }
]);

(我知道使用$ rootScope这样很奇怪,但我只是想提出一个简短的例子。)

示例页面模板:

<fieldset>
  <legend>Preview:</legend>
  <div data-super-thing data-variable-a="false">
  </div>
</fieldset>
<fieldset>
   <legend>Code output:</legend>
   <textarea rows="4" cols="50" data-code-mirror="{{result}}">
   </textarea>
</fieldset>

是否有人将某个指令的内部$编译版本或类似版本注入服务?

1 个答案:

答案 0 :(得分:2)

根据您的需要,我可以提供4种选择:

  • 使用该服务手动创建指令。
  • 创建一个指令,它将html记录在变量中。
  • 创建一个通用指令,通过事件$emit报告其内容html。
  • 创建一个通用指令,它会将你的html记录在变量中(我认为这是首选解决方案。

jsfiddle上的实例。

&#13;
&#13;
angular.module('ExampleApp', [])
  .controller('ExampleController', function($scope, compileDirective) {
    $scope.valueShow = 1234567;
    $scope.array = [1, 23, 4, 5, 9, 6];
    
    $scope.addInArray = function(){
      $scope.array.push(Math.random());
    }
    
    var elem = compileDirective.get(myDirective, {
      val: 1234
    });
    console.log('Compiled by Service', elem);


    $scope.$on('show-compile.html-changed', function(event, value) {
      console.log('html from show-cimpile', value);
    });


  })
  .service('compileDirective', function($compile, $rootScope) {
    return {
      get: function(directiveFn, scope) {
        var directive = myDirective();
        directive.scope = $rootScope.$new(false);
        for (var k in scope)
          directive.scope[k] = scope[k];
        return $compile(directive.template)(directive.scope);
      }
    };
  })
  .directive('myDirective', myDirective)
  .directive('showCompileEvent', function() {
    return {
      restrict: "A",
      link: function(scope, elem) {
        scope.$watch(function() {
          return elem.html();
        }, function(val) {
          scope.$emit('show-compile.html-changed', val);
        });
      }
    };
  }) 
  .directive('showCompile', function() {
    return {
      restrict: "A",
      scope:{showCompile:"="},
      link: function(scope, elem) {
        scope.$watch(function() {
          return elem.html();
        }, function(val) {
          scope.showCompile = val;
        });
      }
    };
  })
  .directive('myDirectives', function() {
    return {
      restrict: "EA",
      replace: true,
      scope: {
        val: "=",
        htmlVal:"="
      },
      template: "<div><b>{{val}}</b></div>",
      link: function(scope, elem) {
        scope.$watch(function() {
          return elem.html();
        }, function(val) {
          scope.$emit('my-directive.html-changed', val);
          scope.htmlVal = val;
        });
      }
    };
  });

function myDirective() {
  return {
    restrict: "EA",
    replace: true,
    scope: {
      val: "="
    },
    template: "<div>{{val}}</div>",
  };

}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="ExampleApp">
  <div ng-controller="ExampleController">
    <my-directive val="valueShow"></my-directive>
    <my-directives val="valueShow" html-val="selfHTML"></my-directives>
    Html for my-directives <pre>{{selfHTML}}</pre>
    <my-directive show-compile-event val="valueShow"></my-directive>
    <button ng-click="addInArray()">
     add in array
    </button>
    <div show-compile="htmlFromNgRepeat">
      <div ng-repeat="a in array">
        {{a}}
      </div>
    </div>
    <pre>{{htmlFromNgRepeat}}</pre>
  </div>
</div>
&#13;
&#13;
&#13;