为什么我无法在AngularJs工厂中获取更新值?

时间:2014-04-19 08:32:55

标签: angularjs angularjs-scope angularjs-factory

我正在尝试更新然后获取AngularJs工厂的更新值,我在一个范围内设置值并尝试在另一个范围内获取它,我正在设置工厂来处理我的应用程序中的弹出消息所以而不是重复我的自我,我只想要一个工厂来处理消息。

myApp.factory('msg',function ($modal) {
    factory = {};

    factory.text = '';
    factory.modal;
    factory.response;

    factory.window = function () {
        this.modal = $modal.open({
            templateUrl:'partials/message/confirm.html',
            controller:'cms'
        });
    }

    factory.setText = function (text) {
        this.text = text;
    }

    factory.getResponse = function () {
        return this.response;
    }

    factory.confirm = function () {
        this.modal.close();
        this.response = true;
    }

    factory.cancel = function () {
        this.modal.close();
        this.response = false;
    }

    factory.confirmSave = function () {
        this.text = 'save';
        this.window();
    }

    factory.confirmUpdate = function () {
        this.text = 'update';
        this.window();
    }

    factory.confirmDelete = function () {
        this.text = 'delete';
        this.window();
    }


    return factory;
});

用户控制器

myApp.controller('users',function ($scope,$location,$http,msg) {
    $http.get('api/v1/users')
    .success(function (data,status) {
        $scope.user = data;
    })
    .error(function (data,status) {
        $location.path('/login');
    });

    $scope.showWrite = function () {
        $scope.write = true;
    }

    $scope.closeWrite = function () {
        $scope.write = false;
        $scope.newUser = '';
    }

    $scope.save = function () {
        $http.post('api/v1/users/store',$scope.newUser)
        .success(function (data,status) {

            $scope.user.unshift({
                first_name: $scope.newUser.first_name,
                last_name: $scope.newUser.last_name,
                email: $scope.newUser.email,
                role: $scope.newUser.role
            });

            $scope.write = false;
            $scope.newUser = '';
        })
        .error(function (data,status) {
            alert('failed');
        });
    }

    $scope.confirmDelete = function (index,id) {
        msg.confirmDelete();
        if(msg.getResponse() === true){
            $http.get('api/v1/users/destroy/'+id)
            .success(function (data,status) {
                $scope.user.splice(index,1);
            })
            .error(function (data,status) {
                alert('failed');
            });
        };
        console.log(msg.getResponse());
    }

    $scope.showUserInfo = function () {

    }

});

1 个答案:

答案 0 :(得分:1)

您提供的代码似乎工作正常,问题出在其他地方,可能在cms控制器或confirm.html模板中。我和您的工厂签了plunker,您可以在那里看到它。

<强>的index.html

<div ng-controller="ctrl1">
  <button ng-click="msg.confirmSave()">confirm save</button>
  <span ng-if="msg.getResponse() !== undefined">Response: {{msg.getResponse()}}</span>
</div>

<强> confirm.html

<h1>{{msg.text}}</h1>
<button ng-click="msg.confirm()">Confirm</button>
<button ng-click="msg.cancel()">Cancel</button>

<强>的JavaScript

angular.module('app',['ui.bootstrap']).
  controller('cms', ['$scope', 'msg', function($scope, msg){
    $scope.msg = msg;
  }]).
  controller('ctrl1', ['$scope', 'msg', function($scope, msg) {
    $scope.msg = msg;
  }]).
  factory('msg',['$modal', function ($modal) {
    // The same code as in the question
  }]);

一些提示:

  • 使用var factory = {};代替factory = {}来声明局部变量,而不是偶尔覆盖全局factory
  • factory.modal;factory.response;没有像您期望的那样在factory对象中声明相关属性,而是返回undefined,所以只需删除它们,因为它们没用了
  • factory.setTextfacory.getResponse是多余的,因为factory.textfactory.responsefactory的公共属性。如果要将它们设为工厂专用,请将它们声明为var text;var response;,并相应地更改存取方法。在这种情况下,将getText添加到工厂也很有用。
  • 如果您计划仅从您的工厂访问factory.modal,最好将其封装到您的工厂(将其设为私有),如上一篇文章中所述。
  • 仅从工厂公开公开API(例如,不要公开window

应用所有提示后,您的工厂可能如下所示:

factory('msg',['$modal', function ($modal) {
    var text = '',
        modal,
        response;

    function window () {
        modal = $modal.open({
            templateUrl:'confirm.html',
            controller:'cms'
        });
    }

    return {
      setText: function (_text_) {
        text = _text_;
      },
      getText: function() {
        return text;
      },
      getResponse: function () {
        return response;
      },
      confirm: function () {
        modal.close();
        response = true;
      },
      cancel: function () {
        modal.close();
        response = false;
      },
      confirmSave: function () {
        text = 'save';
        window();
      },
      confirmUpdate: function () {
        text = 'update';
        window();
      },
      confirmDelete: function () {
        text = 'delete';
        window();
      }
    };
  }]);

这是plunker

<强> 编辑:

用控制器代码更新帖子之后我觉得很清楚:真正的问题是你同步使用confirmDelete(),但它是异步的(因为一旦用户点击确认或取消,将来会返回值) !处理异步工作人员角度有$q服务。要使用它,您应该在factory.confirmSave()factory.confirmUpdate()factory.confirmDelete()中创建延迟对象,返回它的承诺并在factory.confirm()factory.cancel()中解决/拒绝它{1}}。一旦解决或拒绝承诺,您可以从factory获取值或直接将其作为相关回调的参数。

<强>工厂

function confirmDelete() {
  deferred = $q.defer();
  text = this;
  window();
  return deferred.promise;
}

<强>控制器

msg.confirmDelete().then(function(value) {
    // Resolved
    $scope.response = value;
}, function(value) {
    // Rejected
    $scope.response = value;
});

完整示例请参阅以下plunker