Hol*_*lly 5 api ajax angularjs
我正在创建一个Angular App,它对Drupal CMS系统进行ajax调用以获取一些内容.其中一些内容包括来自Facebook,Twitter,Instagram和Youtube的小部件.
ajax调用是用postsController 和完成的postsService.
我无法正确渲染这些社交媒体小部件.当有人直接使用小部件进入页面时,我已经让它们正确呈现,但如果他们改变了路径(页面视图),小部件将无法加载.我相信这是因为API使用的脚本仅在页面加载事件上运行.
起初角度根本没有渲染小部件,但我做了两件事来让它工作.
/platform.twitter.com/widgets.jscompileAjax当用户更改视图/路径时,我该怎么做才能渲染这些内容?
下面是htmldoc中代码的屏幕截图和示例,其中问题在单个htmldoc中复制.小部件在页面加载时正确呈现,但在单击" 转到页面"链接之一时则不会.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.5.9/angular-sanitize.min.js"></script>
<script src="https://code.angularjs.org/1.5.9/angular-route.min.js"></script>
<script type="text/javascript" src="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
<script>
var app = angular.module('app', ['ngSanitize','ngRoute']);
app.config(function($routeProvider) {
$routeProvider.when('/page1', {
controller: 'postsController as postsCtrl',
templateUrl: 'page1.htm'
}).when('/page2', {
controller: 'postsController as postsCtrl',
templateUrl: 'page2.htm'
})
.otherwise({ redirectTo: '/page1' });
});
app.controller('postsController', ['postsService',function(postsService) {
var postsCtrl = this;
postsCtrl.test = 'this is an expression from the controller'
var promise = postsService.getPost(1);
promise.then(function(data) {
postsCtrl.data = data.data;
// I can't access the API on SO so am replicating what I would get from it here.
postsCtrl.twitter = "<div data-oembed-url=\"https:\/\/twitter.com\/NatGeo\/status\/811610711671656448\">\n<div style=\"max-width:320px;margin:auto;\">\n<blockquote align=\"center\" class=\"twitter-tweet\">\n<p dir=\"ltr\" lang=\"en\" xml:lang=\"en\">Polar bears are just one of the animals that will benefit from President Obamas\u00a0recent ban on oil drilling <a href=\"https:\/\/t.co\/MX4ZnX7TNw\">https:\/\/t.co\/MX4ZnX7TNw<\/a><\/p>\n\u2014 National Geographic (@NatGeo) <a href=\"https:\/\/twitter.com\/NatGeo\/status\/811610711671656448\">December 21, 2016<\/a><\/blockquote>\n<script async=\"\" charset=\"utf-8\" src=\"\/\/platform.twitter.com\/widgets.js\"><\/script><\/div>\n<\/div>";
postsCtrl.facebook = "<div data-oembed-url=\"https:\/\/www.facebook.com\/natgeo\/posts\/10154212815083951\">\n<div id=\"fb-root\">\u00a0<\/div>\n<script>\n<!--\/\/--><![CDATA[\/\/ ><!--\n(function(d, s, id) {\n var js, fjs = d.getElementsByTagName(s)[0];\n if (d.getElementById(id)) return;\n js = d.createElement(s); js.id = id;\n js.src = \"\/\/connect.facebook.net\/en_US\/sdk.js#xfbml=1&version=v2.3\";\n fjs.parentNode.insertBefore(js, fjs);\n}(document, 'script', 'facebook-jssdk'));\n\/\/--><!]]>\n<\/script><div class=\"fb-post\" data-href=\"https:\/\/www.facebook.com\/natgeo\/posts\/10154212815083951\" data-width=\"550\">\n<blockquote cite=\"https:\/\/www.facebook.com\/natgeo\/posts\/10154212815083951\" class=\"fb-xfbml-parse-ignore\">\n<p>Inhumane and unsafe, snake wine is often made by drowning a live snake in alcohol. Before you purchase a gift abroad, here are a few things to know.<\/p>\nPosted by <a href=\"https:\/\/www.facebook.com\/natgeo\/\">National Geographic<\/a> on\u00a0<a href=\"https:\/\/www.facebook.com\/natgeo\/posts\/10154212815083951\">Wednesday, December 21, 2016<\/a><\/blockquote>\n<\/div>\n<\/div>"
postsCtrl.instagram = "<div data-oembed-url=\"https:\/\/www.instagram.com\/p\/BOTfVSFDgn-\/?taken-by=natgeo&hl=en\">\n<div style=\"max-width:320px;margin:auto;\"><!-- You're using demo endpoint of Iframely API commercially. Max-width is limited to 320px. Please get your own API key at https:\/\/iframely.com. -->\n<blockquote class=\"instagram-media\" data-instgrm-version=\"7\" style=\" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);\">\n<div style=\"padding:8px;\">\n<div style=\" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;\">\n<div style=\" background:url(data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC\/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5\/P8\/t9FuRVCRmU73JWlzosgSIIZURCjo\/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI\/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf\/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;\">\u00a0<\/div>\n<\/div>\n\n<p style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;\"><a href=\"https:\/\/www.instagram.com\/p\/BOTfVSFDgn-\/\" style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;\" target=\"_blank\">A photo posted by National Geographic (@natgeo)<\/a> on <time datetime=\"2016-12-22T03:35:07+00:00\" style=\" font-family:Arial,sans-serif; font-size:14px; line-height:17px;\">Dec 21, 2016 at 7:35pm PST<\/time><\/p>\n<\/div>\n<\/blockquote>\n<script async=\"\" defer=\"defer\" src=\"\/\/platform.instagram.com\/en_US\/embeds.js\"><\/script><\/div>\n<\/div>\n\n<p>\u00a0<\/p>";
postsCtrl.youtube = "<div data-oembed-url=\"https:\/\/youtu.be\/G51LtqmZKto\">\n<div style=\"max-width:320px;margin:auto;\"><!-- You're using demo endpoint of Iframely API commercially. Max-width is limited to 320px. Please get your own API key at https:\/\/iframely.com. -->\n<div>\n<div style=\"left: 0px; width: 100%; height: 0px; position: relative; padding-bottom: 56.2493%;\"><iframe allowfullscreen=\"\" frameborder=\"0\" src=\"https:\/\/www.youtube.com\/embed\/G51LtqmZKto?wmode=transparent&rel=0&autohide=1&showinfo=0&enablejsapi=1\" style=\"top: 0px; left: 0px; width: 100%; height: 100%; position: absolute;\" tabindex=\"-1\"><\/iframe><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<p>\u00a0<\/p>\n<\/div>\n \n<\/div>"
postsCtrl.slider = "<div class=\"slick-slider\">\n \n <div>Service Slide 1<\/div>\n \n <div>Service Slide 2<\/div>\n \n <div>Service Slide 3<\/div>\n \n <\/div>";
});
}]);
app.service("postsService", function($http, $q) {
function getPost(postsId) {
var deferred = $q.defer()
var url = 'https://jsonplaceholder.typicode.com/albums/' + postsId;
$http({
method: 'GET', // GET OPTIONS
cache: true,
url: url,
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
}).then(function(response) {
//your code when success
deferred.resolve(response);
}, function(response) {
//your code when fails
deferred.reject(response);
});
return deferred.promise;
}
this.getPost = getPost;
});
app.directive('compileAjax', function($compile) {
return {
restrict: 'A',
replace: true,
link: function(scope, elem, attrs) {
scope.$watch(attrs.compileAjax, function(html) {
elem[0].innerHTML = html;
$compile(elem.contents())(scope);
});
}
}
});
app.directive('slickSlider', function() {
return {
restrict: 'C',
link: function(scope, elem, attrs) {
$(elem).slick({
// settings
});
}
}
});
</script>
<script src="//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.5"
async></script>
<script async="" defer="defer" src="//platform.instagram.com/en_US/embeds.js"></script>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</head>
<body>
<body ng-app="app" ng-controller="postsController as postsCtrl">
<script type="text/ng-template" id="page1.htm">
<h2>You're on Page 1</h2>
<a href="#page1">Go to page 1</a>
<a href="#page2">Go to page 2</a>
<div compile-ajax="postsCtrl.twitter"></div>
<div compile-ajax="postsCtrl.facebook"></div>
<div compile-ajax="postsCtrl.instagram"></div>
<div compile-ajax="postsCtrl.youtube"></div>
<div compile-ajax="postsCtrl.slider"></div>
</script>
<script type="text/ng-template" id="page2.htm">
<h2>You're on Page 2</h2>
<a href="#page1">Go to page 1</a>
<a href="#page2">Go to page 2</a>
<div compile-ajax="postsCtrl.twitter"></div>
<div compile-ajax="postsCtrl.facebook"></div>
<div compile-ajax="postsCtrl.instagram"></div>
<div compile-ajax="postsCtrl.youtube"></div>
<div compile-ajax="postsCtrl.slider"></div>
</script>
<div ng-view></div>
</body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
您需要在加载嵌入的小部件后手动初始化它们的 JavaScript,因为小部件是在页面加载后添加的,因此不会被初始化。
\n\n对于推特:
\n\ntwttr.widgets.load();\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n如果内容动态插入到页面中(例如延迟加载内容或使用
\npushState在文章之间导航的技术),则需要请求 Twitter\xe2\x80\x99s 小部件 JavaScript 扫描新按钮和小部件,使用功能twttr.widgets.load()。
对于Instagram:
\n\ninstgrm.Embeds.process();\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n如果要与 HTML 代码分开加载库,可以使用参数调用 oEmbed 端点
\nomitscript。这对于想要自行处理 embeds.js 脚本加载的网站非常有用。要手动初始化嵌入代码,您可以调用 JavaScript 函数instgrm.Embeds.process()。
对于脸书:
\n\nFB.XFBML.parse(); \nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n\n
<fb:like>您可以使用此函数使用 XFBML 语法(例如)或 HTML5 语法(例如<div class="fb-like">)重新渲染社交插件
您必须追踪其他社交媒体嵌入的初始化代码......
\n\n除非您想要在 html 中获取特定的角度绑定/指令,否则编译 html 没有任何意义。
\n\n这是一个基本演示。
\n