能否将一个指令$编译器注入一个服务?

问题描述:

我试图输出directive作为javascriptstring,以便我可以将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> 

有没有办法将指令或类似的内部$编译版本注入到服务中?

+0

你可以显示你想看到作为输出的内容的示例,请? – zhekaus

+0

@zhekaus - 我添加了一个页面模板来显示如何显示输出,但如果你想我也包括最终输出,我也可以这样做。 –

取决于你需要什么,我可以提供4个选项:使用服务手动

  • 创建指令。
  • 创建一个指令,它将把你的html记录在变量中。
  • 创建一个通用指令,它将通过事件$emit报告其内容html。
  • 创建一个共同的指令,它会记录你的HTML变量(这是首选的解决方案,我想。)上jsfiddle

活生生的例子。

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>", 
 
    }; 
 

 
}
<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>