Estoy tratando de actualizar y luego obtener la actualizaciónel valor de una fábrica de AngularJs, estoy configurando el valor en un ámbito y tratando de obtenerlo en otro, estoy configurando una fábrica para manejar los mensajes emergentes en mi aplicación, así que en lugar de repetir mi auto solo quiero una fábrica para manejar la mensajes
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;
});
el controlador de los usuarios
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 () {
}
});
Respuestas
1 para la respuesta № 1Parece que el código que proporcionaste funciona bien y el problema está en otra parte, probablemente en cms
controlador o en confirm.html
modelo. He hecho un plunker Con tu fábrica donde podrás verla en directo.
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
}]);
Algunos consejos:
- Utilizar
var factory = {};
en lugar defactory = {}
con el fin de declarar variable local y no anular globalfactory
de vez en cuando. factory.modal;
yfactory.response;
no declarar propiedades relevantes enfactory
Objeto como esperas, pero regresa.undefined
En su lugar, solo quítenlos, porque son inútiles.factory.setText
yfacory.getResponse
son redundantes, ya quefactory.text
yfactory.response
son propiedades publicas defactory
. Si quieres hacerlos privados a la fábrica, declaralos comovar text;
yvar response;
y cambiar los métodos de acceso en consecuencia. También será útil añadir.getText
a su fábrica en ese caso.- Si planeas acceder
factory.modal
solo desde su fábrica, es mejor incapsularla en su fábrica (hacerla privada) como se describe en la viñeta anterior. - Expone solo la API pública de la fábrica (no exponga
window
por ejemplo)
Después de aplicar todos los consejos, su fábrica puede tener el siguiente aspecto:
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();
}
};
}]);
Aquí hay un plunker.
EDITAR:
Después de actualizar la publicación con el código del controlador, todo está claro para mí: el verdadero problema es que usted usa confirmDelete()
sincrónicamente, pero es asíncrono (ya que devuelve valor en el futuro, una vez que el usuario hace clic en confirmar o cancelar). Para tratar con el personal de asynch angular tiene un $q
Servicio. Para usarlo, debes crear un objeto diferido en factory.confirmSave()
, factory.confirmUpdate()
y factory.confirmDelete()
, devuelve la promesa y resuélvela / recházala en factory.confirm()
y factory.cancel()
. Una vez que la promesa se resuelve o se rechaza, puede obtener el valor de factory
o obténgalo directamente como argumento de devolución de llamada relevante.
fábrica
function confirmDelete() {
deferred = $q.defer();
text = this;
window();
return deferred.promise;
}
controlador
msg.confirmDelete().then(function(value) {
// Resolved
$scope.response = value;
}, function(value) {
// Rejected
$scope.response = value;
});
Ejemplo completo ver en el siguiente plunker.