为什么使用 $compile 使工厂执行多次
Why does using $compile make factory execute multiple times
在我的代码中,我需要从 javascript 回调函数中编译从另一个 api 返回的 html。
以下是我的代码的简化版本。
我正在使用一种工厂方法,该方法使用 $compile 和 $rootScope 重新编译任何元素。
此设置的奇怪之处在于编译函数使数据工厂执行多次。
这是什么原因?
这种编译动态html的方法有什么建议或缺陷吗?
这是个笨蛋linkhttp://plnkr.co/edit/D32kCS4BkslvpBsRtFoS
var app = angular.module('mainApp', []);
app.factory('CompileDirective', function($compile, $rootScope) {
function compileApp() {
$compile($("[ng-app='mainApp']"))($rootScope);
}
return {
compileApp: compileApp
};
});
app.factory('data', function() {
alert("run");
return "data";
});
app.directive('testDirective', function(data) {
return {
restrict: 'E',
templateUrl: 'tpl.html'
};
});
function addDirective() {
$('#container').append('<test-directive></test-directive>');
callback();
}
function callback() {
alert('callback called');
angular.injector(['ng', 'mainApp']).get("CompileDirective").compileApp();
}
<script data-require="angular.js@1.3.7" data-semver="1.3.7" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js"></script>
<script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body ng-app="mainApp">
<script type="text/ng-template" id="tpl.html">
{{ "hello" + "world"}}
</script>
<h1>Hello Plunker!</h1>
<input type="button" value="Add Directive" onClick="addDirective()" />
<div id='container'>
<test-directive></test-directive>
</div>
</body>
就我个人而言,我不会将它放在工厂中,而是添加一个指令来编译代码或在控制器中执行....
如果我理解你正在尝试做的正确,这就是我的建议:
对于静态 html 你已经有了 ng-bind-html
指令......如果你需要它是动态的,只需创建一个这样的指令
angular.module('app',[]).directive('ngHtmlCompile',function ($compile) {
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
// watch the 'compile' expression for changes
return scope.$eval(attrs.ngHtmlCompile);
},
function(value) {
// when the 'compile' expression changes
// assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current
// scope.
// NOTE: we only compile .childNodes so that
// we don't get into infinite loop compiling ourselves
$compile(element.contents())(scope);
}
);
};
});
在我的代码中,我需要从 javascript 回调函数中编译从另一个 api 返回的 html。
以下是我的代码的简化版本。 我正在使用一种工厂方法,该方法使用 $compile 和 $rootScope 重新编译任何元素。
此设置的奇怪之处在于编译函数使数据工厂执行多次。 这是什么原因? 这种编译动态html的方法有什么建议或缺陷吗?
这是个笨蛋linkhttp://plnkr.co/edit/D32kCS4BkslvpBsRtFoS
var app = angular.module('mainApp', []);
app.factory('CompileDirective', function($compile, $rootScope) {
function compileApp() {
$compile($("[ng-app='mainApp']"))($rootScope);
}
return {
compileApp: compileApp
};
});
app.factory('data', function() {
alert("run");
return "data";
});
app.directive('testDirective', function(data) {
return {
restrict: 'E',
templateUrl: 'tpl.html'
};
});
function addDirective() {
$('#container').append('<test-directive></test-directive>');
callback();
}
function callback() {
alert('callback called');
angular.injector(['ng', 'mainApp']).get("CompileDirective").compileApp();
}
<script data-require="angular.js@1.3.7" data-semver="1.3.7" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js"></script>
<script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body ng-app="mainApp">
<script type="text/ng-template" id="tpl.html">
{{ "hello" + "world"}}
</script>
<h1>Hello Plunker!</h1>
<input type="button" value="Add Directive" onClick="addDirective()" />
<div id='container'>
<test-directive></test-directive>
</div>
</body>
就我个人而言,我不会将它放在工厂中,而是添加一个指令来编译代码或在控制器中执行....
如果我理解你正在尝试做的正确,这就是我的建议:
对于静态 html 你已经有了 ng-bind-html
指令......如果你需要它是动态的,只需创建一个这样的指令
angular.module('app',[]).directive('ngHtmlCompile',function ($compile) {
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
// watch the 'compile' expression for changes
return scope.$eval(attrs.ngHtmlCompile);
},
function(value) {
// when the 'compile' expression changes
// assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current
// scope.
// NOTE: we only compile .childNodes so that
// we don't get into infinite loop compiling ourselves
$compile(element.contents())(scope);
}
);
};
});