2014-05-05 46 views
0

我正在開發一個AngularJS SPA的SharePoint 2013應用程序(所以我不認爲SharePoint是一個問題)。AngularJS:數據綁定未按預期工作

在Default.aspx頁,我引用的所有相關腳本:

<!-- 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> 

這裏是我的模板:

<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 --> 

正如你可以看到我使用NG-斗篷,但我也嘗試了ng-bind。

這裏是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 

和控制器:

(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); 
})(); 

最後,這裏是服務:

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 
}); 

根據一切我已閱讀和研究,這應該工作。在console.dir,一切都顯示了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: "[email protected]", 
      Groups: { }, 
      Id: 9, 
      IsHiddenInUI: false, 
      IsSiteAdmin: false, 
      LoginName: "i:0#.f|membership|[email protected]", 
      PrincipalType: 1, 
      Role: "RSC", 
      Title: "Name, My (My Title)", 
      UserId: { } 
     }, 
     this: { } 
    } 
+0

你不應該混'$。當(參考的東西時,才需要)用' Angular.js。 Angular旨在消除對jQuery異步性的需求。 –

+0

我正在關注微軟高級產品營銷經理的編碼,這是目前我所知道的最好的。我希望很快能夠更好地學習Angular和SharePoint。 – jgravois

回答

1

當您使用$.when jQuery的承諾實現,則需要通知角的東西在$scope需要更新。

在這種邏輯的最後,調用$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)); }); 

注:此當你以外的angular-land

+0

document.ready() - 真的嗎?同意擺脫jQuery垃圾 – mortsahl

+0

同意,這是理想的解決方案,但有時候必須重用現有的邏輯和代碼,這就解決了OP試圖解決的問題。 – Brocco

+0

是的,我的評估過於倉促。 Angular可以輕鬆地整合到使用其他框架的現有遺留代碼中。我的評論意思是說,如果你從頭開始創建一個Angular項目,99.9%的時間沒有理由需要jQuery(Angular包括它自己的jqlite版本)。新的Angular開發人員需要以聲明的方式思考真正「獲得」Angular。 – mortsahl