加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs – Angular JS无法在页面/路由更改上呈现社交媒体窗口

发布时间:2020-12-17 18:09:57 所属栏目:安全 来源:网络整理
导读:我正在创建一个Angular App,它对Drupal CMS系统进行ajax调用以获取一些内容.其中一些内容包括来自Facebook,Twitter,Instagram和Youtube的小部件. ajax调用是使用postsController和postsService完成的. 我无法正确渲染这些社交媒体小部件.当有人直接使用小部
我正在创建一个Angular App,它对Drupal CMS系统进行ajax调用以获取一些内容.其中一些内容包括来自Facebook,Twitter,Instagram和Youtube的小部件.

ajax调用是使用postsController和postsService完成的.

我无法正确渲染这些社交媒体小部件.当有人直接使用小部件进入页面时,我已经让它们正确呈现,但如果他们改变了路径(页面视图),小部件将无法加载.我相信这是因为API使用的脚本仅在页面加载事件上运行.

起初角度根本没有渲染小部件,但我做了两件事来让它工作.

>我将CDN链接放在头部的API javascript中,用于wach API,例如/platform.twitter.com/widgets.js
>我使用名为compileAjax的自定义指令更改了我从Drupal获取的数据的角度重新编译

当用户更改视图/路径时,我该怎么做才能渲染这些内容?

下面是html doc中代码的屏幕截图和示例,其中问题在单个html doc中复制.小部件在页面加载时正确呈现,但在单击“转到页面”链接之一时则不会.

enter image description here

<!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',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 Obamasu00a0recent ban on oil drilling <a href="https://t.co/MX4ZnX7TNw">https://t.co/MX4ZnX7TNw</a></p>nu2014 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> onu00a0<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&amp;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.5),0 1px 10px 0 rgba(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>nn<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>nn<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&amp;rel=0&amp;autohide=1&amp;showinfo=0&amp;enablejsapi=1" style="top: 0px; left: 0px; width: 100%; height: 100%; position: absolute;" tabindex="-1"></iframe></div>n</div>n</div>n</div>nn<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',attrs) {
            $(elem).slick({
                // settings
            });
        }
    }
});
</script>
<script src="//connect.facebook.net/en_US/sdk.js#xfbml=1&amp;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>

解决方法

您需要在加载嵌入式窗口小部件后手动初始化嵌入式窗口小部件的javascript,因为窗口小部件是在页面加载后添加的,因此未进行初始化.

对于Twitter:

twttr.widgets.load();

If content is dynamically inserted into a page (such as lazy-loading content or using a pushState technique to navigate between articles) it’s necessary to request Twitter’s widgets JavaScript scan for new buttons and widgets using the twttr.widgets.load() function.

对于Instagram:

instgrm.Embeds.process();

If you want to load the library separately from the HTML code,you can call the oEmbed endpoint with the omitscript parameter. This is useful for websites that want to handle the loading of the embeds.js script by themselves. To manually initialize the embed code,you can then call the JavaScript function instgrm.Embeds.process().

对于Facebook:

FB.XFBML.parse();

You can use this function to re-render social plugins using either the XFBML syntax (e.g. <fb:like>) or the HTML5 syntax (e.g. <div class="fb-like">)

您必须跟踪其他社交媒体嵌入的初始化代码…

编译html没有任何意义,除非你想要获取的html中有特定的角度绑定/指令.

这是basic demo.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读