/ / ¿Por qué no puedo obtener el valor de actualización en una fábrica de AngularJs? - angularjs, angularjs-scope, angularjs-factory

¿Por qué no puedo obtener el valor de actualización en una fábrica de AngularJs? - angularjs, angularjs-scope, angularjs-factory

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 № 1

Parece 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 de factory = {} con el fin de declarar variable local y no anular global factory de vez en cuando.
  • factory.modal; y factory.response; no declarar propiedades relevantes en factory Objeto como esperas, pero regresa. undefined En su lugar, solo quítenlos, porque son inútiles.
  • factory.setText y facory.getResponse son redundantes, ya que factory.text y factory.response son propiedades publicas de factory. Si quieres hacerlos privados a la fábrica, declaralos como var text; y var 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.