草庐IT

javascript - Angular 需要重新加载页面才能显示 fb 共享按钮

coder 2024-07-15 原文

我正在尝试启动并运行 facebooks 共享插件。我遇到的问题是我必须重新加载页面才能真正显示共享按钮。如果我通过链接或 url 导航到页面,facebook 共享按钮将不会显示,我必须重新加载页面,然后按钮才会显示。我正在使用 angular,所以我想使用一个指令,但到目前为止我的努力还没有成功。

这里是我的模板中的指令

<div class="fb-share-button" fb-share data-href="{{fbUrl}}" data-layout="button" id='fb-share'></div>

这是我的指令。

angular.module('App').directive('fbShare', function () {
    function createHTML(href, layout) {
        return '<div class="fb-share-button" ' +
                       'data-href="' + href + '" ' +
                       'data-layout="' + layout + '" ' +
               '</div>';
    }

    return {
        restrict: 'A',
        scope: {},
        link: function postLink(scope, elem, attrs) {
        attrs.$observe('dataHref', function (newValue) {
                var href        = newValue;
                var layout    = attrs.layout    || 'button';

                elem.html(createHTML(href, layout));
                FB.XFBML.parse(elem[0]);
            });
        }
    };
});

facebook sdk代码,紧跟在开始的body标签之后

  <div id="fb-root"></div>
  <script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.5&appId=xxxxxxxxxx";
  fjs.parentNode.insertBefore(js, fjs);
  }(document, 'script', 'facebook-jssdk'));
  </script>

最佳答案

这是一组很棒的 Angular 共享小部件指令集,包括 FB:http://plnkr.co/edit/OvZRK6?p=preview

只需设置您的 FB APP ID 并为您的 url、imageURl 和名称使用一个范围变量。

如果您查看他的代码,您可以看到如何呈现代码并可能根据您的需要自定义 FB 模板。

angular.module('myApp', ['angulike'])
  .run([
    '$rootScope',
    function($rootScope) {
      $rootScope.facebookAppId = '85024842290'; // set your facebook app id here
    }
  ]);

angular.module('myApp')
  .controller('myController', [
    '$scope',
    function($scope) {
      $scope.myModel = {
        Url: 'http://jasonwatmore.com/post/2014/08/01/AngularJS-directives-for-social-sharing-buttons-Facebook-Like-GooglePlus-Twitter-and-Pinterest.aspx',
        Name: "AngularJS directives for social sharing buttons - Facebook, Google+, Twitter and Pinterest | Jason Watmore's Blog",
        ImageUrl: 'http://www.jasonwatmore.com/pics/jason.jpg'
      };
    }
  ]);


/**
 * AngularJS directives for social sharing buttons - Facebook Like, Google+, Twitter and Pinterest
 * @author Jason Watmore <jason@pointblankdevelopment.com.au> (http://jasonwatmore.com)
 * @version 1.2.0
 */
(function() {
  angular.module('angulike', [])

  .directive('fbLike', [
    '$window', '$rootScope',
    function($window, $rootScope) {
      return {
        restrict: 'A',
        scope: {
          fbLike: '=?'
        },
        link: function(scope, element, attrs) {
          if (!$window.FB) {
            // Load Facebook SDK if not already loaded
            $.getScript('//connect.facebook.net/en_US/sdk.js', function() {
              $window.FB.init({
                appId: '85024842290',
                xfbml: true,
                version: 'v2.0'
              });
              renderLikeButton();
            });
          } else {
            renderLikeButton();
          }

          var watchAdded = false;

          function renderLikeButton() {
            if (!!attrs.fbLike && !scope.fbLike && !watchAdded) {
              // wait for data if it hasn't loaded yet
              watchAdded = true;
              var unbindWatch = scope.$watch('fbLike', function(newValue, oldValue) {
                if (newValue) {
                  renderLikeButton();

                  // only need to run once
                  unbindWatch();
                }

              });
              return;
            } else {
              element.html('<div class="fb-like"' + (!!scope.fbLike ? ' data-href="' + scope.fbLike + '"' : '') + ' data-layout="button_count" data-action="like" data-show-faces="true" data-share="true"></div>');
              $window.FB.XFBML.parse(element.parent()[0]);
            }
          }
        }
      };
    }
  ])

  .directive('googlePlus', [
    '$window',
    function($window) {
      return {
        restrict: 'A',
        scope: {
          googlePlus: '=?'
        },
        link: function(scope, element, attrs) {
          if (!$window.gapi) {
            // Load Google SDK if not already loaded
            $.getScript('//apis.google.com/js/platform.js', function() {
              renderPlusButton();
            });
          } else {
            renderPlusButton();
          }

          var watchAdded = false;

          function renderPlusButton() {
            if (!!attrs.googlePlus && !scope.googlePlus && !watchAdded) {
              // wait for data if it hasn't loaded yet
              watchAdded = true;
              var unbindWatch = scope.$watch('googlePlus', function(newValue, oldValue) {
                if (newValue) {
                  renderPlusButton();

                  // only need to run once
                  unbindWatch();
                }

              });
              return;
            } else {
              element.html('<div class="g-plusone"' + (!!scope.googlePlus ? ' data-href="' + scope.googlePlus + '"' : '') + ' data-size="medium"></div>');
              $window.gapi.plusone.go(element.parent()[0]);
            }
          }
        }
      };
    }
  ])

  .directive('tweet', [
    '$window', '$location',
    function($window, $location) {
      return {
        restrict: 'A',
        scope: {
          tweet: '=',
          tweetUrl: '='
        },
        link: function(scope, element, attrs) {
          if (!$window.twttr) {
            // Load Twitter SDK if not already loaded
            $.getScript('//platform.twitter.com/widgets.js', function() {
              renderTweetButton();
            });
          } else {
            renderTweetButton();
          }

          var watchAdded = false;

          function renderTweetButton() {
            if (!scope.tweet && !watchAdded) {
              // wait for data if it hasn't loaded yet
              watchAdded = true;
              var unbindWatch = scope.$watch('tweet', function(newValue, oldValue) {
                if (newValue) {
                  renderTweetButton();

                  // only need to run once
                  unbindWatch();
                }
              });
              return;
            } else {
              element.html('<a href="https://twitter.com/share" class="twitter-share-button" data-text="' + scope.tweet + '" data-url="' + (scope.tweetUrl || $location.absUrl()) + '">Tweet</a>');
              $window.twttr.widgets.load(element.parent()[0]);
            }
          }
        }
      };
    }
  ])

  .directive('pinIt', [
    '$window', '$location',
    function($window, $location) {
      return {
        restrict: 'A',
        scope: {
          pinIt: '=',
          pinItImage: '=',
          pinItUrl: '='
        },
        link: function(scope, element, attrs) {
          if (!$window.parsePins) {
            // Load Pinterest SDK if not already loaded
            (function(d) {
              var f = d.getElementsByTagName('SCRIPT')[0],
                p = d.createElement('SCRIPT');
              p.type = 'text/javascript';
              p.async = true;
              p.src = '//assets.pinterest.com/js/pinit.js';
              p['data-pin-build'] = 'parsePins';
              p.onload = function() {
                if (!!$window.parsePins) {
                  renderPinItButton();
                } else {
                  setTimeout(p.onload, 100);
                }
              };
              f.parentNode.insertBefore(p, f);
            }($window.document));
          } else {
            renderPinItButton();
          }

          var watchAdded = false;

          function renderPinItButton() {
            if (!scope.pinIt && !watchAdded) {
              // wait for data if it hasn't loaded yet
              watchAdded = true;
              var unbindWatch = scope.$watch('pinIt', function(newValue, oldValue) {
                if (newValue) {
                  renderPinItButton();

                  // only need to run once
                  unbindWatch();
                }
              });
              return;
            } else {
              element.html('<a href="//www.pinterest.com/pin/create/button/?url=' + (scope.pinItUrl || $location.absUrl()) + '&media=' + scope.pinItImage + '&description=' + scope.pinIt + '" data-pin-do="buttonPin" data-pin-config="beside"></a>');
              $window.parsePins(element.parent()[0]);
            }
          }
        }
      };
    }
  ]);

})();
<!DOCTYPE html>
<html ng-app="myApp">

<head>
  <meta charset="utf-8" />
  <title>AngularJS directives for social sharing buttons - Facebook Like, Google+, Twitter and Pinterest</title>
  <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
</head>

<body>
  <div ng-controller="myController" class="jumbotron text-center">
    <div class="container">
      <div fb-like></div>
      <div class="col-xs-3">
        <div fb-like="myModel.Url"></div>
      </div>
      <div class="col-xs-3">
        <div tweet="myModel.Name" tweet-url="myModel.Url"></div>
      </div>
      <div class="col-xs-3">
        <div google-plus="myModel.Url"></div>
      </div>
      <div class="col-xs-3">
        <div pin-it="myModel.Name" pin-it-image="myModel.ImageUrl" pin-it-url="myModel.Url"></div>
      </div>
    </div>
  </div>
  <div class="credits text-center">
    <p>
      <a href="http://www.jasonwatmore.com/post/2014/08/01/AngularJS-directives-for-social-sharing-buttons-Facebook-Like-GooglePlus-Twitter-and-Pinterest.aspx">AngularJS directives for social sharing buttons</a>
    </p>
    <p>
      <a href="http://www.jasonwatmore.com">www.jasonwatmore.com</a>
    </p>
  </div>
  <script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
  <script src="https://code.angularjs.org/1.2.16/angular.js"></script>
  <script src="angulike.js"></script>
  <script src="app.js"></script>
</body>

</html>

关于javascript - Angular 需要重新加载页面才能显示 fb 共享按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33382110/

有关javascript - Angular 需要重新加载页面才能显示 fb 共享按钮的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  5. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  6. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  7. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  8. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  9. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  10. ruby-on-rails - link_to 不显示任何 rails - 2

    我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article

随机推荐