Вопрос

I am working on a SharePoint 2013 App which is an AngularJS SPA (so I don't think SharePoint is an issue).

In the Default.aspx page, I am referencing all pertinent scripts:

    <!-- Add your JavaScript to the following file -->
    <script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="../Scripts/angular.js"></script>
    <script type="text/javascript" src="../Scripts/angular-route.js"></script>
    <script type="text/javascript" src="../Scripts/bootstrap.min.js"></script>
    <script type="text/javascript" src="../Scripts/ui-bootstrap-tpls-0.10.0.min.js"></script>
    <script type="text/javascript" src="../Scripts/moment.min.js"></script>

    <!-- ANGULARJS APPLICATION FILES -->
    <script type="text/javascript" src="../App/App.js"></script>
    <script type="text/javascript" src="../App/Controllers/main.js"></script>
    <script type="text/javascript" src="../App/Services/SharePointJSOMService.js"></script>

And here is my template:

<div data-ng-app="appITI">
    <div data-ng-controller="MainController">
        <div id="header" class="clr-darkblue">
        <a href="#">
            <img src="../Images/head_logo.gif">
        </a>
        <span class="sp_controls" data-ng-cloak="">
            Welcome {{currentUser.Title}}
            &nbsp;&nbsp;|&nbsp;&nbsp;
            <a id="btnPreferences" data-ng-click="prefs = true">My Settings</a>
            &nbsp;&nbsp;|&nbsp;&nbsp;
            Role: {{currentUser.Role}}
            &nbsp;&nbsp;|&nbsp;&nbsp;
            <a href="#">Logout</a>
        </span>
        </div> <!-- /#header -->
    </div> <!-- /mainController -->
</div> <!-- /ANGULAR APP -->

As you can see I am using ng-cloak but I have also tried ng-bind.

here is App.js

var appITI = angular.module('appITI', ['ui.bootstrap']);

var hostweburl;
var appweburl;
var currentUser;

$(document).ready(function () {
    SP.SOD.executeOrDelayUntilScriptLoaded(runMyCode, "SP.js");
    function runMyCode(){} // end runMyCode fn
}); // end Document.Ready

and the controller:

(function(){
    var MainController = function($scope, SharePointJSOMService){
        SP.SOD.executeOrDelayUntilScriptLoaded(runMyCode, "SP.js");
        function runMyCode(){

        //get currentUser
        $.when(SharePointJSOMService.getCurrentUser())
        .done(function(jsonObject){
            currentUser = jsonObject.d;
            $scope.currentUser = currentUser;
            $scope.currentUser.Role = "RSC";
            console.dir($scope);
        }).fail(function(err){ console.info(JSON.stringify(err)); });

        } // end runMyCode fn
    }; // end MainController

    MainController.$inject = ['$scope', 'SharePointJSOMService'];

    angular.module('appITI').controller('MainController', MainController);
})();

Lastly, here is the service:

appITI.service('SharePointJSOMService', function($q, $http){
    this.getCurrentUser = function(){
        var deferred = $.Deferred();

        JSRequest.EnsureSetup();
        hostweburl = decodeURIComponent(JSRequest.QueryString["SPHostUrl"]);
        appweburl = decodeURIComponent(JSRequest.QueryString["SPAppWebUrl"]);

        var userid = _spPageContextInfo.userId;
        var restQueryUrl = appweburl + "/_api/web/getuserbyid(" + userid + ")";

        var executor = new SP.RequestExecutor(appweburl);
        executor.executeAsync({
            url: restQueryUrl,
            method: "GET",
            headers: { "Accept": "application/json; odata=verbose" },
            success: function(data, textStatus, xhr){
                deferred.resolve(JSON.parse(data.body));
            },
            error: function(xhr, textStatus, errorThrown){
                deferred.reject(JSON.stringify(xhr));
            }
        });
        return deferred;
    }; // /getCurrentUser fn
});

According to everything I have read and studied, this should work. In the console.dir, everything is shown for currentUser:

{
       [functions]: ,
       $$asyncQueue: [ ],
       $$childHead: null,
       $$childTail: null,
       $$destroyed: false,
       $$isolateBindings: { },
       $$listenerCount: { },
       $$listeners: { },
       $$nextSibling: null,
       $$phase: null,
       $$postDigestQueue: [ ],
       $$prevSibling: null,
       $$watchers: [ ],
       $id: "003",
       $parent: { },
       $root: { },
       currentUser: {
          [functions]: ,
          __metadata: { },
          Email: "my.name@company.mail.onmicrosoft.com",
          Groups: { },
          Id: 9,
          IsHiddenInUI: false,
          IsSiteAdmin: false,
          LoginName: "i:0#.f|membership|my.name@corporate.com",
          PrincipalType: 1,
          Role: "RSC",
          Title: "Name, My (My Title)",
          UserId: { }
       },
       this: { }
    }
Это было полезно?

Решение

When you are using $.when jQuery's promise implementation you will need to notify angular that something in the $scope needs updated.

At the end of this logic, call $scope.$apply():

$.when(SharePointJSOMService.getCurrentUser())
    .done(function(jsonObject){
        currentUser = jsonObject.d;
        $scope.currentUser = currentUser;
        $scope.currentUser.Role = "RSC";
        console.dir($scope);
        $scope.$apply(); // <-- tell angular to update the scope and refresh the UI
    }).fail(function(err){ console.info(JSON.stringify(err)); });

Note: this is only needed when you are referencing something outside of angular-land

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top