绑定Angularjs到新创建的html元素动态 [英] Bind Angularjs to newly created html element dynamically
问题描述
我有,一旦随叫随到点击的服务来回报一些数据多个选项卡标签页。一些数据返回HTML形式,非常随意。我想收集被输入的那些值和经由服务发送数据返回给服务器。我的问题是,我无法从我动态创建的HTML输入元素获取数据。
我创建了一个 Plunker 表明问题是什么。请注意,HTML值可以在任何时候改变,因此硬编码的HTML将无法工作。在这里,从plunker的code,但请看plunker为怎么回事的最佳视角。
app.js
VAR应用= angular.module('plunker',[]);app.controller('MainCtrl',函数($范围,SCE $,$编译){
$ scope.name ='世界';
$ scope.html =; $ scope.htmlElement =功能(){
VAR HTML =<输入类型='文本'NG-模式='HTML'>< /输入>中;
返回$ sce.trustAsHtml(HTML);
}});
的index.html
<!DOCTYPE HTML>
< HTML NG-应用=plunker> < HEAD>
<间的charset =UTF-8/>
<标题> AngularJS Plunker< /标题>
<脚本>的document.write('<基本href =+ document.location +'/>');< / SCRIPT>
<链接rel =stylesheet属性HREF =style.css文件/>
&所述; SCRIPT SRC =https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular.js>&下; /脚本>
&所述; SCRIPT SRC =app.js>&下; /脚本>
< /头> <机身NG控制器=MainCtrl>
< P>您好{{名}}<!/ P> < DIV NG绑定-HTML =HTML元素()>< / DIV> {{HTML}} < /身体GT;< / HTML>
一个解决方案是使用ngInclude以$ templateCache,如本的 Plunker 。
有几件事情要注意。
首先,你可以使用服务这里获取您的模板,并将其添加到$ templateCache,描述 (例如复制):
myApp.service('myTemplateService',['$ HTTP,$ templateCache',函数($ HTTP,$ templateCache){
$ HTTP(/ * ... * /)。然后(功能(结果){
$ templateCache.put(我的动态模板,结果);
});
}]);
然后你可以将其包含在您的模板如下:
< DIV NG-包括='我的动态模板'>< / DIV>
ngInclude将允许在HTML字符串数据绑定,所以你不需要ngBindHtml。
第二个问题是,作为ngInclude创建一个新的范围,访问新建范围,除非你通过一个对象来访问它不能正常工作之外的 HTML
属性父范围(如 NG-模式=data.html
而不是 NG-模式=HTML
。注意, $ scope.data = {}
父范围是什么使得在这种情况下ngInclude范围的HTML以外访问。
(见这个答案了解为什么你应该总是使用在ngModels一个点。)
修改
正如你指出的那样,使用服务时,返回的HTML ngInclude选项是有用的要少得多。
下面是编辑过的 plunker 与使用$编译基于指令的解决方案,如在大卫的上述评论。
相关加法:
app.directive('customHtml',函数($编译,$ HTTP){
返回{
链接:功能(范围,元素,ATTRS){
$ http.get('template.html'),然后(功能(结果){
element.replaceWith($编译(result.data)(范围));
});
}
}
})
I have a tab page with multiple tabs that once clicked on call a service to return some data. Some of that data returns html forms and are very random. I want to collect those values that are entered and send the data via a service back to the server. The problem I have is that I can't get the data from the input elements in the html I'm creating dynamically.
I've created a Plunker to show what the issue is. Note that the html value can change at any time so hard-coding the html won't work. Here the code from the plunker, but please look at the plunker for the best view of whats going on.
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $sce, $compile) {
$scope.name = 'World';
$scope.html = "";
$scope.htmlElement = function(){
var html = "<input type='text' ng-model='html'></input>";
return $sce.trustAsHtml(html);
}
});
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<div ng-bind-html="htmlElement()"></div>
{{html}}
</body>
</html>
One solution would be to use ngInclude with $templateCache, as demonstrated in this Plunker.
There are a couple things to note.
The first is that you can fetch your template using a service and add it to the $templateCache, as described here (example copied):
myApp.service('myTemplateService', ['$http', '$templateCache', function ($http, $templateCache) {
$http(/* ... */).then(function (result) {
$templateCache.put('my-dynamic-template', result);
});
}]);
Then you can include it in your template as follows:
<div ng-include="'my-dynamic-template'"></div>
ngInclude will allow databinding on the html string, so you don't need ngBindHtml.
The second is that, as ngInclude creates a new scope, accessing the html
property outside of the newly created scope won't work properly unless you access it via an object on the parent scope (e.g. ng-model="data.html"
instead of ng-model="html"
. Notice that the $scope.data = {}
in the parent scope is what makes the html accessible outside of the ngInclude scope in this case.
(See this answer for more on why you should always use a dot in your ngModels.)
Edit
As you pointed out, the ngInclude option is much less useful when using a service to return the HTML.
Here's the edited plunker with a directive-based solution that uses $compile, as in David's comment above.
The relevant addition:
app.directive('customHtml', function($compile, $http){
return {
link: function(scope, element, attrs) {
$http.get('template.html').then(function (result) {
element.replaceWith($compile(result.data)(scope));
});
}
}
})
这篇关于绑定Angularjs到新创建的html元素动态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!