2015-05-31 92 views
3

下面的代碼工作正常。我只是想看看是否有更好的方式來編寫它,以便我可以在我的控制器中避免使用$scope.$apply()

當用戶點擊"Sign Up"按鈕時,呼叫將轉到Controller然後轉到Service以及Callback方法。在服務中,我在調用解析雲代碼來創建用戶並在收到響應後調用回調。

問題是我必須在回調方法中調用$scope.$apply()才能將更改應用到綁定到span的vm.m.resp屬性。

有沒有辦法將整個註冊過程作爲單個事務運行並避免回調?

OR

有沒有辦法避免調用$scope.$apply()

這是我的UI看起來像:

<ion-view title="Sign Up"> 
    <ion-content class="has-header"> 
    <div class="list"> 
     <label class="item item-input"> 
     <span class="input-label">Username</span> 
     <input type="text" ng-model="vm.m.username"> 
     </label> 
     <label class="item item-input"> 
     <span class="input-label">Password</span> 
     <input type="password" ng-model="vm.m.password"> 
     </label> 
     <label class="item"> 
     <button class="button button-block button-positive" ng-click="vm.doSignUp()">Sign Up</button> 
     </label> 
    </div> 
    <div class="list"> 
     <div class="bar bar-header bar-positive"> 
     <span ng-bind="vm.m.resp"></span> 
     </div> 
    </div> 
    </ion-content> 
</ion-view> 

這是我的控制器看起來像:

(function() { 
    'use strict'; 

    angular.module('app').controller('UserAdminCtrl', ['$stateParams', '$scope', 'userAdminApi', UserAdminCtrl]); 

    function UserAdminCtrl($stateParams, $scope, userAdminApi) { 
     var vm = this; 
     vm.m = {}; 
     vm.m.username = ''; 
     vm.m.password = ''; 
     vm.m.resp = ''; 

     function doSignUp() { 

      userAdminApi.doSignup(vm.m, doSignUpCallback); 
      vm.m.resp = 'Signing up. Please wait...'; 
     } 

     function doSignUpCallback(resp) { 
      vm.m.resp = resp; 
      $scope.$apply() 
     } 
     vm.doSignUp = doSignUp; 
     vm.doSignUpCallback = doSignUpCallback; 
    }; 
})(); 

這是我的服務看起來像:

(function() { 
    'use strict'; 

    angular.module('app').factory('userAdminApi', [userAdminApi]); 

    function userAdminApi() { 

     function doSignup(m,cb) { 

      Parse.Cloud.run('createUser', {m}, { 
       success: function (result) { 
        cb(result); 
       }, 
       error: function (error) { 
        cb(error.message); 
       } 
      }); 
     } 

     return { 
      doSignup: doSignup 
     }; 
    }; 
})(); 
+2

這是'$ scope.apply()'可能無法避免的一種用例。使用'$ scope.apply()'的主要原因是觸發摘要,只要非角度代碼修改應用程序中的變量而不需要角度知識。 – Claies

+1

你可以用'$ q'包裝任何承諾。 –

+0

@ DanielA.White:你的意思是用$ q包裝工廠中的doSignUp函數? – Asdfg

回答

3

你可以使用承諾回到摘要週期:

(function() { 
    'use strict'; 

    angular.module('app').factory('userAdminApi', ['$q', userAdminApi]); 

    function userAdminApi($q) { 

     function doSignup(m) { 
      var deferred = $q.defer(); 
      Parse.Cloud.run('createUser', {m}, { 
       success: function (result) { 
        deferred.resolve(result); 
       }, 
       error: function (error) { 
        deferred.reject(error); 
       } 
      }); 
      return deferred.promise; 
     } 

     return { 
      doSignup: doSignup 
     }; 
    }; 
})(); 

這給你一個很好的乾淨的錯誤回調以及。