回答

11

下面是角socialshare(具有共享計數器)是目前最流行的/活性GitHub上的替代:

http://github.com/esvit/angular-social

下面是一個簡化的共享按鈕(沒有計數器)。該指令使用Font Awesome作爲依賴項。

http://github.com/tinacious/angular-easy-social-share


有關的元數據拼搶和單頁的應用程序的注意事項

請記住,社交網絡爬蟲,這刮HTML元數據的豐富網頁摘要(如OpenGraph指向圖像和說明),不要評估JavaScript。這可以將標題中的某些元標記呈現爲共享框中的{{括號內}}表達式,而不是動態加載的內容......假設您有通過AngularJS動態加載的元數據。

看看這篇文章關於與角度分享豐富網頁摘要,你應該有一個要求:http://www.michaelbromley.co.uk/blog/171/enable-rich-social-sharing-in-your-angularjs-app

0

考慮sinisterOrange的答案,我想補充一點,有關於邁克爾·布羅姆利的優雅的解決方案信息的一些重要的部分。

爲了有多個條件將您的url重定向到將正確呈現元標記的腳本,您必須多次爲每個規則應用條件。

最後你必須爲你的應用程序訪問做一個負面條件。

<ifModule mod_rewrite.c> 
    RewriteEngine On 

    RewriteCond %{HTTP_USER_AGENT} (facebookexternalhit/[0-9]|Twitterbot|Pinterest|Google.*snippet) 
    RewriteRule ^post/([A-Za-z0-9-]+)/([0-9-]+)$ http://www.example.com/api/renderMetaTags/post/$2 [P,L] 

    RewriteCond %{HTTP_USER_AGENT} (facebookexternalhit/[0-9]|Twitterbot|Pinterest|Google.*snippet) 
    RewriteRule ^location/([A-Za-z0-9-]+)/([0-9-]+)$ www.example.com/api/renderMetaTags/location/$2 [P,L] 

    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteCond %{REQUEST_URI} !index 

    #this condition for crawlers not to interfere with normal access 
    RewriteCond %{HTTP_USER_AGENT} !(facebookexternalhit/[0-9]|Twitterbot|Pinterest|Google.*snippet) 

    #this rule for html5 mode and friendly urls without the # 
    RewriteRule ^(.*)$ /#/$1 [L] 

</ifModule> 

就是這樣。我知道這有點偏離主題,但我失去了寶貴的時間來到這個解決方案。

1

存在是很容易的解決方案,正常工作與我,

您可以重命名你的index.html的index.php

,幷包括有一個代碼來解析URL並基於PHP頁面URL參數您可以添加標題和說明,圖像Twitter和Facebook

這裏包括在我的索引PHP頁面的代碼

<? 

function curPageURL() { 
$pageURL = 'http'; 
if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";} 
$pageURL .= "://"; 
if ($_SERVER["SERVER_PORT"] != "80") { 
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"]; 
} else { 
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]; 
} 
return $pageURL; 
} 




$parse = parse_url(curPageURL()); 

$urlArray = explode("/",$parse['path']); 

$urlPage = $urlArray[2]; 

if($urlPage == "profile"){ 
$image = "profile-img.jpg"; 
$title = "Title of the page "; 
$desc = "Description of Profile the page "; 
$websiteUrl = "Http://example.com"; 
}elseif($urlPage == "news"){ 
$title = "Title of the News page "; 
$desc = "Description of the page "; 
$websiteUrl = "Http://example.com"; 
} 

?> 


<meta http-equiv="content-type" content="text/html; charset=utf-8"> 
<title><? echo $title; ?></title> 


<meta property="twitter:card" content="summary" /> 
<meta property="twitter:site" content="<? echo $websiteUrl; ?>" /> 
<meta property="twitter:title" content="<? echo $title; ?>" /> 
<meta property="twitter:description" content="<? echo $description; ?>" /> 
<meta property="twitter:image" content="<? echo $image; ?>" /> 
<meta property="twitter:url" content="<? echo curPageURL(); ?>" /> 

<meta property="og:title" content="<? echo $title; ?>" /> 
<meta property="og:description" content="<? echo $description; ?>" /> 
<meta property="og:image" content="<? echo $image; ?>" /> 
<meta property="og:type" content="article" /> 
<meta property="og:site_name" content="<? echo $website_name; ?>" /> 
<meta property="og:url" content="<? echo curPageURL(); ?>" /> 
0

考慮這個解決方案,它使用MVC 5角JS

在索引頁拷貝代碼

<!DOCTYPE html> 
<html> 
<head> 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script> 
<link rel="stylesheet" href="style.css" /> 
<script src="script.js"></script> 
<script src='test.js'></script> 
<script src="http://platform.twitter.com/widgets.js"></script> 
</head> 
<body ng-app='testing'> 
<div ng-controller='temp'> 
    <div facebook class="facebookShare" data-title='{{title}}' data-picture-url='http://i.imgur.com/WACv9Cl.jpg' data-url='{{url}}' data-shares='shares' data-callback='callback'>{{ shares }} </div> 
<br /> 
    <a twitter data-count='horizontal' data-url='{{url}}' data-size="medium" data-text='{{text}}'></a> 
    <br /><br /> 
    <div class="linkedinShare" linkedin data-url='{{url}}' data-title='{{title}}' data-summary="{{text}}" data-shares='linkedinshares'>{{linkedinshares}}</div> 
    <br /><br /> 
    <div gplus data-size="tall" data-annotation="bubble" data-href='{{url}}' data-action='share'></div> 
</div> 
</body> 
</html> 

在腳本中爲我工作。JS寫這個下面提到代碼

angular.module('testing', ['djds4rce.angular-socialshare']) 
.run(function ($FB) { 
$FB.init('Facebook App Id'); 
}); 

angular.module('testing').controller('temp', function ($scope, $timeout)  { 

$timeout(function() { 
    $scope.url = 'http://google.com'; 
    $scope.text = 'testing share'; 
    $scope.title = 'title1' 
}, 1000) 
$timeout(function() { 
    $scope.url = 'https://www.youtube.com/watch?v=wxkdilIURrU'; 
    $scope.text = 'testing second share'; 
    $scope.title = 'title2'; 
}, 1000) 

$scope.callback = function (response) { 
    console.log(response); 
} 
}); 

該代碼可用於指令

angular.module('djds4rce.angular-socialshare', []) 
.factory('$FB', ['$window', function ($window) { 
    return { 
     init: function (fbId) { 
      if (fbId) { 
       this.fbId = fbId; 
       $window.fbAsyncInit = function() { 
        FB.init({ 
         appId: fbId, 
         channelUrl: 'app/channel.html', 
         status: true, 
         xfbml: true 
        }); 
       }; 
       (function (d) { 
        var js, 
         id = 'facebook-jssdk', 
         ref = d.getElementsByTagName('script')[0]; 
        if (d.getElementById(id)) { 
         return; 
        } 

        js = d.createElement('script'); 
        js.id = id; 
        js.async = true; 
        js.src = "//connect.facebook.net/en_US/all.js"; 

        ref.parentNode.insertBefore(js, ref); 

       }(document)); 
      } else { 
       throw ("FB App Id Cannot be blank"); 
      } 
     } 
    }; 

}]).directive('facebook', ['$http', function ($http) { 
    return { 
     scope: { 
      callback: '=', 
      shares: '=' 
     }, 
     transclude: true, 
     template: '<div class="facebookButton">' + 
      '<div class="pluginButton">' + 
      '<div class="pluginButtonContainer">' + 
      '<div class="pluginButtonImage">' + 
      '<button type="button">' + 
      '<i class="pluginButtonIcon img sp_plugin-button-2x sx_plugin-button-2x_favblue"></i>' + 
      '</button>' + 
      '</div>' + 
      '<span class="pluginButtonLabel">Share</span>' + 
      '</div>' + 
      '</div>' + 
      '</div>' + 
      '<div class="facebookCount">' + 
      '<div class="pluginCountButton pluginCountNum">' + 
      '<span ng-transclude></span>' + 
      '</div>' + 
      '<div class="pluginCountButtonNub"><s></s><i></i></div>' + 
      '</div>', 
     link: function (scope, element, attr) { 
      attr.$observe('url', function() { 
       if (attr.shares && attr.url) { 
        $http.get('https://api.facebook.com/method/links.getStats?urls=' + attr.url + '&format=json').success(function (res) { 
         var count = res[0] ? res[0].total_count.toString() : 0; 
         var decimal = ''; 
         if (count.length > 6) { 
          if (count.slice(-6, -5) != "0") { 
           decimal = '.' + count.slice(-6, -5); 
          } 
          count = count.slice(0, -6); 
          count = count + decimal + 'M'; 
         } else if (count.length > 3) { 
          if (count.slice(-3, -2) != "0") { 
           decimal = '.' + count.slice(-3, -2); 
          } 
          count = count.slice(0, -3); 
          count = count + decimal + 'k'; 
         } 
         scope.shares = count; 
        }).error(function() { 
         scope.shares = 0; 
        }); 
       } 
       element.unbind(); 
       element.bind('click', function (e) { 
        FB.ui({ 
         method: 'share', 
         href: attr.url 
        }, function (response) { 
         if (scope.callback !== undefined && typeof scope.callback === "function") { 
          scope.callback(response); 
         } 
        }); 
        e.preventDefault(); 
       }); 
      }); 
     } 
    }; 
}]).directive('facebookFeedShare', ['$http', function ($http) { 
    return { 
     scope: { 
      callback: '=', 
      shares: '=' 
     }, 
     transclude: true, 
     template: '<div class="facebookButton">' + 
      '<div class="pluginButton">' + 
      '<div class="pluginButtonContainer">' + 
      '<div class="pluginButtonImage">' + 
      '<button type="button">' + 
      '<i class="pluginButtonIcon img sp_plugin-button-2x sx_plugin-button-2x_favblue"></i>' + 
      '</button>' + 
      '</div>' + 
      '<span class="pluginButtonLabel">Share</span>' + 
      '</div>' + 
      '</div>' + 
      '</div>' + 
      '<div class="facebookCount">' + 
      '<div class="pluginCountButton pluginCountNum">' + 
      '<span ng-transclude></span>' + 
      '</div>' + 
      '<div class="pluginCountButtonNub"><s></s><i></i></div>' + 
      '</div>', 
     link: function (scope, element, attr) { 
      attr.$observe('url', function() { 
       if (attr.shares && attr.url) { 
        $http.get('https://api.facebook.com/method/links.getStats?urls=' + attr.url + '&format=json').success(function (res) { 
         var count = res[0] ? res[0].total_count.toString() : 0; 
         var decimal = ''; 
         if (count.length > 6) { 
          if (count.slice(-6, -5) != "0") { 
           decimal = '.' + count.slice(-6, -5); 
          } 
          count = count.slice(0, -6); 
          count = count + decimal + 'M'; 
         } else if (count.length > 3) { 
          if (count.slice(-3, -2) != "0") { 
           decimal = '.' + count.slice(-3, -2); 
          } 
          count = count.slice(0, -3); 
          count = count + decimal + 'k'; 
         } 
         scope.shares = count; 
        }).error(function() { 
         scope.shares = 0; 
        }); 
       } 
       element.unbind(); 
       element.bind('click', function (e) { 
        FB.ui({ 
         method: 'feed', 
         link: attr.url, 
         picture: attr.picture, 
         name: attr.name, 
         caption: attr.caption, 
         description: attr.description 
        }, function (response) { 
         if (scope.callback !== undefined && typeof scope.callback === "function") { 
          scope.callback(response); 
         } 
        }); 
        e.preventDefault(); 
       }); 
      }); 
     } 
    }; 
}]).directive('twitter', ['$timeout', function ($timeout) { 
    return { 
     link: function (scope, element, attr) { 
      var renderTwitterButton = debounce(function() { 
       if (attr.url) { 
        $timeout(function() { 
         element[0].innerHTML = ''; 
         twttr.widgets.createShareButton(
          attr.url, 
          element[0], 
          function() { }, { 
           count: attr.count, 
           text: attr.text, 
           via: attr.via, 
           size: attr.size 
          } 
         ); 
        }); 
       } 
      }, 75); 
      attr.$observe('url', renderTwitterButton); 
      attr.$observe('text', renderTwitterButton); 
     } 
    }; 
}]).directive('linkedin', ['$timeout', '$http', '$window', function ($timeout, $http, $window) { 
    return { 
     scope: { 
      shares: '=' 
     }, 
     transclude: true, 
     template: '<div class="linkedinButton">' + 
      '<div class="pluginButton">' + 
      '<div class="pluginButtonContainer">' + 
      '<div class="pluginButtonImage">in' + 
      '</div>' + 
      '<span class="pluginButtonLabel"><span>Share</span></span>' + 
      '</div>' + 
      '</div>' + 
      '</div>' + 
      '<div class="linkedinCount">' + 
      '<div class="pluginCountButton">' + 
      '<div class="pluginCountButtonRight">' + 
      '<div class="pluginCountButtonLeft">' + 
      '<span ng-transclude></span>' + 
      '</div>' + 
      '</div>' + 
      '</div>' + 
      '</div>', 
     link: function (scope, element, attr) { 
      var renderLinkedinButton = debounce(function() { 
       if (attr.shares && attr.url) { 
        $http.jsonp('https://www.linkedin.com/countserv/count/share?url=' + attr.url + '&callback=JSON_CALLBACK&format=jsonp').success(function (res) { 
         scope.shares = res.count.toLocaleString(); 
        }).error(function() { 
         scope.shares = 0; 
        }); 
       } 
       $timeout(function() { 
        element.unbind(); 
        element.bind('click', function() { 
         var url = encodeURIComponent(attr.url).replace(/'/g, "%27").replace(/"/g, "%22") 
         $window.open("//www.linkedin.com/shareArticle?mini=true&url=" + url + "&title=" + attr.title + "&summary=" + attr.summary); 
        }); 
       }); 
      }, 100); 
      attr.$observe('url', renderLinkedinButton); 
      attr.$observe('title', renderLinkedinButton); 
      attr.$observe('summary', renderLinkedinButton); 
     } 
    }; 
}]).directive('gplus', [function() { 
    return { 
     link: function (scope, element, attr) { 
      var googleShare = debounce(function() { 
       if (typeof gapi == "undefined") { 
        (function() { 
         var po = document.createElement('script'); 
         po.type = 'text/javascript'; 
         po.async = true; 
         po.src = 'https://apis.google.com/js/platform.js'; 
         po.onload = renderGoogleButton; 
         var s = document.getElementsByTagName('script')[0]; 
         s.parentNode.insertBefore(po, s); 
        })(); 
       } else { 
        renderGoogleButton(); 
       } 
      }, 100); 
      //voodo magic 
      var renderGoogleButton = (function (ele, attr) { 
       return function() { 
        var googleButton = document.createElement('div'); 
        var id = attr.id || randomString(5); 
        attr.id = id; 
        googleButton.setAttribute('id', id); 
        element.innerHTML = ''; 
        element.append(googleButton); 
        if (attr.class && attr.class.indexOf('g-plusone') != -1) { 
         window.gapi.plusone.render(id, attr); 
        } else { 
         window.gapi.plus.render(id, attr); 
        } 
       } 
      }(element, attr)); 
      attr.$observe('href', googleShare); 
     } 
    }; 
}]); 

function debounce(func, wait, immediate) { 
var timeout; 
return function() { 
    var context = this, 
     args = arguments; 
    var later = function() { 
     timeout = null; 
     if (!immediate) func.apply(context, args); 
    }; 
    var callNow = immediate && !timeout; 
    clearTimeout(timeout); 
    timeout = setTimeout(later, wait); 
    if (callNow) func.apply(context, args); 
}; 
}; 
function randomString(len, an) { 
an = an && an.toLowerCase(); 
var str = "", 
    i = 0, 
    min = an == "a" ? 10 : 0, 
    max = an == "n" ? 10 : 62; 
for (; i++ < len;) { 
    var r = Math.random() * (max - min) + min << 0; 
    str += String.fromCharCode(r += r > 9 ? r < 36 ? 55 : 61 : 48); 
} 
return str; 
}