2

I am trying to update and then get the update value of an AngularJs factory, I am setting the value in one scope and trying to get it in another, I am setting a factory to handle the pop up messages in my app so instead of repeating my self I want just one factory to handle the messages.

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

the users controller

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 () {

    }

});
4

1 に答える 1

1

あなたが提供したコードは正常に動作しているようで、問題はおそらくcmsコントローラーまたはconfirm.htmlテンプレートのどこかにあるようです。私はあなたがそれをライブで見ることができるあなたの工場でプランカーを作りました.

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>

確認.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;で関連するプロパティを宣言しませんが、代わりに戻ります。それらは役に立たないため、削除してくださいfactoryundefined
  • factory.setTextとは のパブリック プロパティであるため、facory.getResponse冗長です。それらをファクトリに対してプライベートにしたい場合は、それらをandとして宣言し、それに応じてアクセサ メソッドを変更します。その場合、工場に追加することも役立ちます。factory.textfactory.responsefactoryvar 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();
      }
    };
  }]);

これがプランカーです。

編集:

コントローラーコードで投稿を更新した後、すべてが明確になりました。本当の問題は、confirmDelete()同期的に使用していることですが、非同期です(ユーザーが確認またはキャンセルをクリックすると、将来値が返されるため)! 非同期スタッフAngularに対処するための$qサービスがあります。それを使用するには、 と で遅延オブジェクトを作成しfactory.confirmSave()、その promise を返し、factory.confirmUpdate()factory.confirmDelete()で解決/拒否する必要がfactory.confirm()ありfactory.cancel()ます。factorypromise が解決または拒否されると、関連するコールバックの引数として、値をフェッチまたは直接取得できます。

工場

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を参照してください。

于 2014-04-19T11:34:34.427 に答える