Подтвердить что ты не робот

Почему мой виджет Twitter не будет отображаться, если я изменил вид в angularjs?

Привет и спасибо за чтение.

У меня есть приложение angular imx, и ive наткнулся на проблему. настроен таким образом

index.html -

<html ng-app="myApp">
...
<div ng-view></div>
<div ng-include="'footer.html'"></div>
...
</html>

Я не буду помещать свои маршруты в довольно простой/домашний, показывает /home/index.html и т.д.

/home/index.html(представление по умолчанию, когда вы приходите на сайт)

<div class="responsive-block1">
<div class="tweet-me">
    <h1> tweet me </h1>
</div>

<div class="twitter-box">
    <twitter-timeline></twitter-timeline>
</div>

twitter директива временной шкалы

directives.directive("twitterTimeline", function() {
return { 
     restrict: 'E',
     template: '<a class="twitter-timeline" href="#" onclick="location.href='https://twitter.com/NAME'; return false;" data-widget-id="XXXXXXXXXXXXXX">Tweets by @NAME</a>',
     link: function(scope, element, attrs) {

    function run(){
        (!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs"));
        console.log('run script');
    };

    run();


     }
   };
});

Итак, я только что создал базовую директиву twitter, используя тег из твиттера. Но когда я меняю пример представления на /blog, а затем возвращаюсь в /home, виджет твиттера больше не отображается вообще.

Im также использует $anchorScroll, и если я все равно перейду на страницу, этот виджет также исчезнет. Любая информация будет большой благодарностью.

4b9b3361

Ответ 1

Смотрите это сообщение: https://dev.twitter.com/discussions/890

Я думаю, что вы сможете получить виджет для повторной обработки, вызвав  twttr.widgets.load().

Если вы обнаружите, что это не сработает, вам нужно будет обернуть этот код в $timeout в вашем контроллере:

    controller('MyCtrl1', ['$scope', '$timeout', function ($scope, $timeout) {
            $timeout = twttr.widgets.load();
    }])

Ответ 2

Настроить ответ Sir l33tname:

В объявлении услуг:

    angular.module('app.services', []).
      service('tweetWidgets', function() {

        this.loadAllWidgets = function() {

            /* widgets loader code you get when 
             * declaring you widget with Twitter 
             * this code is the same for all widgets 
             * so calling it once will reference whatever
             * widgets are active in the current ng-view */

            !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
         };

         this.destroyAllWidgets = function() {
            var $ = function (id) { return document.getElementById(id); };
            var twitter = $('twitter-wjs');
            if (twitter != null)
                twitter.remove();
         };  
      });

Затем в объявлениях контроллера:

    angular.module('app.controllers', []).
      controller('view_1_Controller', tweetWidgets) {

         // load them all
         tweetWidgets.loadAllWidgets();

     }).

       controller('view_2_Controller', tweetWidgets) {

          // now destroy them :>
          tweetWidgets.destroyAllWidgets();

     });

Теперь, когда вы оставляете представление № 1 для просмотра № 2, ваш контроллер для просмотра № 2 удалит виджеты, связанные с представлением № 1, и когда вы вернетесь к виду №1, виджеты будут повторно установлены.

Ответ 3

Проблема заключается в том, что когда Angular переключает представления, тег script, который был первоначально вставлен, не удаляется из документа. Я исправил это на своем собственном веб-сайте, удалив элемент Twitter script всякий раз, когда моя директива Timeline Timeline отсутствует в представлении. См. Код ниже с комментариями.

 function (scope, el, attrs) {
     el.bind('$destroy', function() {
         var twitterScriptEl = angular.element('#twitter-wjs');
         twitterScriptEl.remove();
     });

     // function provided by Twitter that been formatted for easier reading
     function (d, s, id) {
         var js, fjs = d.getElementsByTagName(s)[0], p = /^http:/.test(d.location) ? 'http' : 'https';

         // If the Twitter script element is already on the document this will not get called. On a regular webpage that gets reloaded this isn't a problem. Angular views are loaded dynamically.
         if (!d.getElementById(id)) {
             js = d.createElement(s);
             js.id = id;
             js.src = p + "://platform.twitter.com/widgets.js";
             js.parentNode.insertBefore(js, fjs);
         }
     }(document, "script", "twitter-wjs");        
 }

Ответ 4

В основном это то, что говорят Loc Nguyen.

Поэтому каждый раз, когда вы его воссоздаете, вы должны сначала удалить его.

var $ = function (id) { return document.getElementById(id); };
function loadTwitter() {!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");}

var twitter = $('twitter-wjs');
twitter.remove();
loadTwitter(); 

Ответ 5

Ответ от @b1r3k работает без проблем:

поместите это в свой контроллер:

$timeout(function () { twttr.widgets.load(); }, 500); 

Ответ 6

Для тех, кто пытается загрузить twttr.widgets.load() внутри своего контроллера, вы, скорее всего, получите сообщение об ошибке, которое twttr не определено AT НЕКОТОРЫЕ ТОЧКИ в вашем UX, потому что асинхронный вызов для загрузки твиттера script может не быть завершено к моменту создания экземпляра контроллера и ссылок twttr.

Итак, я создал этот TwitterService

.factory('TwitterService', ['$timeout', function ($timeout) {
    return {
        load: function () {
        if (typeof twttr === 'undefined') {
            (function() {
                !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
            })();
        } else {
            $timeout = twttr.widgets.load();
        };
        }
    }
}])

а затем вызовите TwitterService.load() внутри контроллеров, которым требуются ваши виджеты. Это работало очень хорошо. Он в основном просто проверяет, существует ли объект twttw, и если это так, просто перезагрузите script... иначе просто перезагрузите script.

Не уверен, что это лучшая реализация, но похоже, что все другие решения имеют крайние случаи, когда они будут вызывать ошибку. Мне еще предстоит найти эту альтернативу.