工厂的功能不起作用,但在控制器中使用时它起作用。为什么呢?

时间:2015-07-09 17:50:44

标签: angularjs

我有一个名为updatedUser()的函数,我在工厂中定义。如果我注入工厂并将该函数分配给要在视图中使用的作用域然后调用它,则它无法正常工作。我希望它能够更新用户。相反,它只是创建一个新用户。

然而,当我使用相同的函数并在控制器中定义它并在视图中调用它时,它按预期工作。我不明白!任何帮助将不胜感激。

这是我的代码:

(function(){
  'use strict';

  angular
  .module('casemanagerApp')
  .factory('$cmUserData', $cmUserData);

  function $cmUserData($log, Restangular) {

    return {
      users: users,
      getUser: getUser,
      updateUser: updateUser
    };

    function users() {
      return Restangular.service('users');
    }

    function getUser() {
      return users().one(1).get().$object;
    }

    function updateUser() {
      Restangular.all('users')
      .post(getUser())
      .then(function(){
        $log.info('User updated');
      });
    }

  }

})();

控制器

(function() {
  'use strict';

  angular
  .module('casemanagerApp')
  .controller('CasePlanGoalsCtrl', CasePlanGoalsCtrl);

  function CasePlanGoalsCtrl($log, $cmUserData) {
    var vm = this;

    // Injections
    vm.user = $cmUserData.getUser();

    // Functions
    // vm.updateUser = $cmUserData.updateUser; <-This doesn't work
    vm.updateUser = updateUser; // This will work

    function updateUser() {
      Restangular.all('users')
      .post(vm.user)
      .then(function() {
        $log.info(vm.user.firstName + ' was updated');
      });
    }

  }

})();

查看。见ng-change

<md-switch 
    aria-label="Stack Cards" 
    ng-model="vm.user.settings.stackCards" 
    ng-true-value="'isStacked'" 
    ng-false-value="'!isStacked'" 
    ng-change="vm.updateUser()" 
    class="text-uppercase-small pull-right">
    Stack Cards
</md-switch>

2 个答案:

答案 0 :(得分:1)

你的控制器正在工作,但它实际上做的不同于你的工厂。在调用Restangular.getUser()以填充该变量之后很久就使用vm.user对象。为了打破您的控制器并使其功能与您的工厂相同,请更改此:

function updateUser() {
  Restangular.all('users')
  .post(vm.user)
  .then(function() {
    $log.info(vm.user.firstName + ' was updated');
  });
}

function updateUser() {
  Restangular.all('users')
  .post($cmUserData.getUser())
  .then(function() {
    $log.info(vm.user.firstName + ' was updated');
  });
}

你的控制器给Restangular一个机会来解析它正在调用的对象,而你的服务正在调用getUser函数并立即尝试使用它的结果来进行POST。

如果上述代码与您的服务中断的方式相同,那么您至少知道问题发生的原因。这是因为Restangular正在为您提供一个它承诺填充的对象,但是当您的服务updateUser函数尝试使用该对象时,它还没有被填充。

当您调用getUser时,Restangular会立即返回一个对象,但此时该对象中只有!当来自服务器的调用返回时,它是一个Restangular将填充的shell。您需要确保将实际用户对象传递给工厂。

对此没有明显的答案。也许您在工厂中缓存了getUser的结果,或者您可能将用户传递到updateUser()工厂函数中。我怀疑Restangular有一种方式它暗示你这样做,但我并不熟悉它,所以我不能帮助那些特定的那些。

答案 1 :(得分:1)

需要将vm.user传递给工厂的updateUser()函数,因为所有令人敬畏的东西@shieldstroy说:

(function(){
  'use strict';

  angular
  .module('casemanagerApp')
  .factory('$cmUserData', $cmUserData);

  function $cmUserData($log, Restangular) {

    return {
      users: users,
      getUser: getUser,
      updateUser: updateUser
    };

    function users() {
      return Restangular.service('users');
    }

    function getUser() {
      return users().one(1).get().$object;
    }

    function updateUser(model) {
      Restangular.all('users')
      .post(model)
      .then(function(){
        $log.info('User updated');
      });
    }

  }

})();

控制器

(function() {
  'use strict';

  angular
  .module('casemanagerApp')
  .controller('CasePlanGoalsCtrl', CasePlanGoalsCtrl);

  function CasePlanGoalsCtrl($log, $cmUserData) {
    var vm = this;

    // Injections
    vm.user = $cmUserData.getUser();

    // Functions
    vm.updateUser = $cmUserData.updateUser;

  }

})();

查看。见ng-change

<md-switch 
    aria-label="Stack Cards" 
    ng-model="vm.user.settings.stackCards" 
    ng-true-value="'isStacked'" 
    ng-false-value="'!isStacked'" 
    ng-change="vm.updateUser(vm.user)" 
    class="text-uppercase-small pull-right">
    Stack Cards
</md-switch>