Javascript AngularJS:在API返回的HTML中编译指令
因此,我可以访问正在使用的REST API,该API返回以下预生成的HTML:Javascript AngularJS:在API返回的HTML中编译指令,javascript,angularjs,angularjs-directive,angularjs-compile,Javascript,Angularjs,Angularjs Directive,Angularjs Compile,因此,我可以访问正在使用的REST API,该API返回以下预生成的HTML: <p class="p"> <sup id="John.3.16" class="v">16</sup> <span class="wj">“For </span> <span class="wj">God so loved </span> <span class="wj">the worl
<p class="p">
<sup id="John.3.16" class="v">16</sup>
<span class="wj">“For </span>
<span class="wj">God so loved </span>
<span class="wj">the world,</span>
<span class="wj">that he gave his only Son, that whoever believes in him should not </span>
<span class="wj">perish but have eternal life.</span>
</p>
16
“因为
上帝如此爱我
世界,,
他将独生子赐给他,叫信他的人不可离开他
灭亡,却有永生。
这对我学习AngularJS提出了一个有趣的新挑战。我无法控制从API返回的HTML,因为它不是我构建的API
我试图做的(这可能是完全错误的方法)是在“v”类上构建一个类指令,这样我就可以向韵文编号添加一个ng click属性,并将韵文信息传递到应用程序的另一部分
下面是我目前拥有的代码,它似乎没有做任何事情,尽管我认为它会
var app = angular.module('ProjectTimothy');
app.filter("sanitize", ['$sce', function($sce) {
return function(htmlCode){
return $sce.trustAsHtml(htmlCode);
}
}]);
app.controller("timothy.ctrl.search", ['$scope', '$http', function($scope, $http){
$scope.url = "http://apiendpoint.com/";
$scope.copyright = "";
$scope.search = function() {
// Make the request to the API for the verse that was entered
// Had to modify some defaults in $http to get post to work with JSON data
// but this part is working well now
$http.post($scope.url, { "query" : $scope.searchwords, "version": "eng-ESV"})
.success(function(data, status) {
// For now I'm just grabbing parts of the object that I know exists
$scope.copyright = data.response.search.result.passages[0].copyright;
$scope.result = data.response.search.result.passages[0].text;
})
.error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
};
}]);
app.directive("v", ['$compile', function($compile) {
return {
restrict: 'C',
transclude: true,
link: function(scope, element, attrs) {
element.html("<ng-transclude></ng-transclude>").show();
$compile(element.contents())(scope);
},
scope: { id:'@' },
/*template: "<ng-transclude></ng-transclude>",*/
replace: false
};
}]);
var-app=angular.module('ProjectTimothy');
app.filter(“消毒”、['$sce',函数($sce){
返回函数(htmlCode){
返回$sce.trustAsHtml(htmlCode);
}
}]);
app.controller(“timothy.ctrl.search”、['$scope','$http',函数($scope,$http){
$scope.url=”http://apiendpoint.com/";
$scope.copyright=“”;
$scope.search=函数(){
//向API请求输入的诗句
//为了让post处理JSON数据,必须修改$http中的一些默认值
//但这部分现在运行良好
$http.post($scope.url,{“query”:$scope.searchwords,“version”:“eng ESV”})
.成功(功能(数据、状态){
//现在我只是抓住我知道存在的物体的一部分
$scope.copyright=data.response.search.result.passions[0]。版权所有;
$scope.result=data.response.search.result.passions[0].text;
})
.错误(功能(数据、状态){
$scope.data=data | |“请求失败”;
$scope.status=状态;
});
};
}]);
app.directive(“v”[“$compile”,函数($compile){
返回{
限制:“C”,
是的,
链接:函数(范围、元素、属性){
html(“”.show();
$compile(element.contents())(范围);
},
作用域:{id:'@'},
/*模板:“”*/
替换:false
};
}]);
使用API返回的HTML填充的HTML模板:
<div class="bible_verse_search_container" ng-controller="timothy.ctrl.search">
<div class="input-group">
<input type="text" class="form-control" placeholder="Bible Verse To Read (i.e. John 11:35)" ng-model="searchwords">
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="search()">Search</button>
</span>
</div>
<div class="well" ng-show="copyright" ng-bind-html="copyright | sanitize"></div>
<div ng-bind-html="result | sanitize"></div>
</div>
搜寻
因此,我希望将HTML填充到绑定HTML的底部div中,然后以某种方式调用$compile来转换“v”类sup的指令,我可以修改。再一次,我是相当新的角度,所以可能有一个超级简单的方法来做这件事,就像大多数其他事情在Anguler,我只是还没有找到
实际上,最终目标是将每个韵文编号转换为自己的指令,使其能够单击并访问其具有的id属性,以便我可以将该信息与一些用户内容一起发送回我自己的API
这感觉像是很多信息,所以如果有任何不清楚的地方,请告诉我。我会继续努力,所以如果我先弄清楚,我一定会更新答案
正在进行中
检查此问题:
现在我想知道,尝试将显示诗句的部分转换为一个指令,然后让搜索控制器用服务器上的HTML填充一个范围变量,然后用它作为指令的模板,是否更有意义……我想你的第二种方法是——转换这个部分n将诗句显示在指令中,这是一种很好的方式 您可以替换此:
<div ng-bind-html="result | sanitize"></div>
有这样的指令:
<verse-display verse-html="{{result}}"></verse-display>
app.directive('verseDisplay', ['$compile', function($compile) {
function handleClickOnVerse(e) {
var verseNumber = e.target.id;
// do what you want with the verse number here
}
return {
restrict: 'E',
scope: {
verseHtml: '@'
},
replace: true,
transclude: false,
template: '<div ng-bind-html="verseHtml | sanitize"></div>',
link: function(scope, element, attrs) {
$compile(element.contents())(scope);
element.on('click', '.v', handleClickOnVerse);
}
};
}]);
指令定义如下所示:
<verse-display verse-html="{{result}}"></verse-display>
app.directive('verseDisplay', ['$compile', function($compile) {
function handleClickOnVerse(e) {
var verseNumber = e.target.id;
// do what you want with the verse number here
}
return {
restrict: 'E',
scope: {
verseHtml: '@'
},
replace: true,
transclude: false,
template: '<div ng-bind-html="verseHtml | sanitize"></div>',
link: function(scope, element, attrs) {
$compile(element.contents())(scope);
element.on('click', '.v', handleClickOnVerse);
}
};
}]);
app.directive('verseDisplay',['$compile',函数($compile){
函数handleClickOnVerse(e){
var verseNumber=e.target.id;
//你想怎么做就怎么做
}
返回{
限制:'E',
范围:{
verseHtml:“@”
},
替换:正确,
排除:错误,
模板:“”,
链接:函数(范围、元素、属性){
$compile(element.contents())(范围);
元素上('click','.v',handleClickOnVerse);
}
};
}]);
因此,您可以将自己的单击处理程序应用于元素
这是一个。(打开控制台,看到诗句编号被注销。)可能是我在这里发布的最不明智的事情,但它是一个非常酷的代码。我不知道我是否建议实际运行它,但这里有一个 因此,我称之为不明智的原因之一是,注入的代码将运行您所拥有的任何指令,而不仅仅是您想要的指令。除此之外,可能还有许多其他安全风险。但它的工作原理非常棒。如果您信任正在检索的HTML,请尝试使用它 查看小提琴,了解代码的其余部分:
function unwiseCompile($compile) {
return function (scope, element, attrs) {
var compileWatch = scope.$watch(
function (scope) { return scope.$eval(attrs.unwiseCompile); },
function (unwise) {
element.html(unwise);
$compile(element.contents())(scope);
// for better performance, compile once then un-watch
if (scope.onlyOnce) {
// un-watch
compileWatch();
}
});
};
}