Afficher les sites suivis dans le bandeau avec KnockoutJS– 3
J’avais envie de découvrir KnockoutJS (KO) et coder la même fonctionnalité m’a paru être un bon exercice pratique.
Première différence : comme KO préfère le JSON, j’ai fait appel aux fonctionnalités de suivi avec des appels REST plutôt que par le ClientContext.
Deuxième différence : l’utilisation de MVVM (Modèle-Vue-VueModèle) propose un confort certains à la lecture et la maintenance du code.
Dans ce cadre d’utilisation et vu mes connaissances, KO m’a bien plu. Simple à appréhender, il permet d’avoir un code plus propre sans trop d’effort. Le nombre de ligne est sensiblement le même mais comme c’est plus lisible et maintenable, on gagne à l’utiliser.
Astuce :
Lorsque l’on utilise la méthode POST dans une page SharePoint, il faut penser à passer le formDigest au risque d’avoir pour réponse : ‘The security validation for this page is invalid »
var formDigest = $("[name='__REQUESTDIGEST']").val();
$.ajax({
headers: { "X-RequestDigest": formDigest }
Les lignes nécessaires sont surlignées dans le code JavaScript.
<ul class="ms-core-menu-list" id="custom-sites-menu">
<LI>
<DIV class="subcontainer" data-bind="foreach: sites">
<DIV data-bind="attr: { id: CleanId }">
<SPAN class=ms-core-menu-link>
<A data-bind="attr: { href: Uri }"><span data-bind="text: Name"></span></A>
<A data-bind="click: $root.removeFollowedSite" >
<IMG src="/_layouts/15/images/CAA.RSE.Communities/UnfollowWhite.png" width=20 height=20>
</A>
</SPAN>
</DIV>
</DIV>
</LI>
<LI class=clear>
<a class="ms-core-menu-link footer" data-bind="attr: { href: personnalSite}">
Ma page de suivi
</a>
</LI>
</ul>
<script type='text/javascript' src='/_layouts/15/CAA.RSE.Communities/js/knockout-3.1.0.js'></script>
<script src="/_layouts/15/CAA.RSE.Communities/js/gla-followedsites-ko.js" type="text/javascript"></script>
<link href="/_layouts/15/CAA.RSE.Communities/css/gla-followedsites.css" rel="stylesheet" type="text/css"/>
// AJAX - Post data to stop following a site
function stopFollowingSite(siteUrl, cleanSiteId) {
var stopFollowingUrl = "http://sps2013/sites/test/_api/social.following/stopfollowing(ActorType=2,ContentUri=@v,Id=null)?@v='"+ siteUrl + "'"
var formDigest = $("[name='__REQUESTDIGEST']").val();
$.ajax({
url: stopFollowingUrl,
type: "POST",
headers: { "ACCEPT": "application/json;odata=verbose", "X-RequestDigest": formDigest },
success: function(data){},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status + " : " + thrownError);
//alert(xhr.responseText);
}
});
}
// wrapper
function FollowedSite(data) {
this.Name = ko.observable(data.Name);
this.Uri = ko.observable(data.Uri);
this.CleanId = ko.computed(function() {return data.Id.split(".").join("");}, this);
}
function TaskListViewModel() {
// Data
var self = this;
self.sites = ko.observableArray([]);
self.personnalSite = ko.observable();
self.removeFollowedSite = function(site) {
stopFollowingSite(site.Uri(), site.CleanId());
self.sites.remove(site)
};
// AJAX - Get all sites the current user is following
var requestFollowedUri = _spPageContextInfo.webAbsoluteUrl + "/_api/social.following/my/followed(types=4)";
$.ajax({
url: requestFollowedUri,
type: "GET",
headers: { "ACCEPT": "application/json;odata=verbose" },
success: function(data){
var mappedFollowedSites = $.map(data.d.Followed.results, function(item) { return new FollowedSite(item) });
self.sites(mappedFollowedSites);
},
error: function(){alert("Failed to get followed sites.");
}
});
// AJAX - Get current user's personnal site
var requestFollowedSiteUri = _spPageContextInfo.webAbsoluteUrl + "/_api/social.following/my/followedsitesuri";
$.ajax({
url: requestFollowedSiteUri,
type: "GET",
headers: { "ACCEPT": "application/json;odata=verbose" },
success: function(data){self.personnalSite(data.d.FollowedSitesUri);},
error: function(){alert("Failed to get personnel site.");
}
});
}
ko.applyBindings(new TaskListViewModel());
jQuery(document).ready(function () {
//add link in SuiteLink
var navU = jQuery("#suiteLinksBox > ul.ms-core-suiteLinkList");
var addNode = jQuery("<a id='Suite_CustomSites_ShellAddNew' href='#' class='ms-core-suiteLink-a' />")
.append(jQuery("<span/>")
.text("Communaut351s")
.append(jQuery("<span class='ms-suitenav-downarrowBox'/>")
.append(jQuery("<img class='ms-suitenav-downarrowIcon' src='/_layouts/15/images/spcommon.png?rev=23' />"))
)
);
// retrieve KO generated menu
var menu = jQuery("#custom-sites-menu");
newLi = jQuery("<li/>").attr("class", "ms-core-suiteLink")
.append(addNode)
.append(menu);
navU.prepend(newLi);
});
Références:
Afficher les sites suivis dans le bandeau