我有一个带有多个选项卡的选项卡页,一旦单击该选项卡,就会调用服务以返回一些数据。其中一些数据返回html表单,并且非常随机。我想收集输入的值,并通过服务将数据发送回服务器。我的问题是无法从正在动态创建的html中的输入元素中获取数据。
我创建了一个Plunker来显示问题所在。请注意,html值可以随时更改,因此对html进行硬编码将无法使用。在这里,代码来自plunker,但是请查看plunker,以获取最新动态。
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>
一种解决方案是将ngInclude与$ templateCache一起使用,如本Plunker所示。
有几件事要注意。
第一个是,你可以使用服务获取您的模板,并将其添加到$templateCache,(例如复制):
myApp.service('myTemplateService', ['$http', '$templateCache', function ($http, $templateCache) { $http(/* ... */).then(function (result) { $templateCache.put('my-dynamic-template', result); }); }]);
然后可以将其包含在模板中,如下所示:
<div ng-include="'my-dynamic-template'"></div>
ngInclude将允许对html字符串进行数据绑定,因此您不需要ngBindHtml。
第二个原因是,当ngInclude创建新作用域时,html除非您通过父作用域上的对象(例如ng- model="data.html"而不是)访问新创建作用域之外的属性,否则将无法正常访问该属性(ng- model="html"请注意,$scope.data={}父作用域中的是是什么使得html在ngInclude范围之外可以访问。
html
ng- model="data.html"
ng- model="html"
$scope.data={}
编辑
正如您所指出的那样,使用服务返回HTML时,ngInclude选项的用处不大。
这是经过编辑的plunker,具有使用$ compile的基于指令的解决方案,如上述David的评论所示。
相关补充:
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)); }); } } })