/ / Dlaczego nie mogę uzyskać wartości aktualizacji w fabryce AngularJs? - angularjs, angularjs-scope, angularjs-factory

Dlaczego nie mogę uzyskać wartości aktualizacji w fabryce AngularJs? - angularjs, angularjs-scope, angularjs-factory

Próbuję zaktualizować, a następnie pobrać aktualizacjęwartość fabryki AngularJs, ustawiam wartość w jednym zakresie i próbuję uzyskać ją w innym, ustawiam fabrykę do obsługi wyskakujących komunikatów w mojej aplikacji, więc zamiast powtarzać się, chcę, aby tylko jedna fabryka obsługiwała wiadomości.

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

kontroler użytkowników

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

}

});

Odpowiedzi:

1 dla odpowiedzi № 1

Wygląda na to, że podany przez Ciebie kod działa poprawnie, a problem jest gdzieś indziej, prawdopodobnie w cms kontroler lub w confirm.html szablon. zrobiłem plunker z twoją fabryką, gdzie możesz to zobaczyć na żywo.

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

Kilka porad:

  • Posługiwać się var factory = {}; zamiast factory = {} aby zadeklarować zmienną lokalną, a nie nadpisać globalną factory sporadycznie.
  • factory.modal; i factory.response; nie deklaruj odpowiednich właściwości w factory obiekt zgodnie z oczekiwaniami, ale wróć undefined zamiast tego po prostu je usuń, ponieważ są bezużyteczne
  • factory.setText i facory.getResponse są zbędne, ponieważ factory.text i factory.response są publicznymi właściwościami factory. Jeśli chcesz, aby były prywatne w fabryce, zadeklaruj je jako var text; i var response; i odpowiednio zmień metody dostępu. Przyda się też dodaćgetText w takim przypadku do twojej fabryki.
  • Jeśli planujesz uzyskać dostęp factory.modal tylko z Twojej fabryki, lepiej zainkasulować go w swojej fabryce (utajnić) tak, jak opisano w poprzednim podpunkcie.
  • Udostępniaj tylko publiczne API z fabryki (nie ujawniaj window na przykład)

Po zastosowaniu wszystkich wskazówek Twoja fabryka może wyglądać następująco:

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

Tutaj jest plunker.

EDYTOWAĆ:

Po zaktualizowaniu posta kodem kontrolera wszystko jest dla mnie jasne: prawdziwym problemem jest to, że używasz confirmDelete() synchronicznie, ale asynchronicznie (ponieważ zwraca wartość w przyszłości, po kliknięciu przez użytkownika potwierdzenia lub anulowania)! Aby poradzić sobie z asynchronicznym personelem kątowym ma $q usługa. Aby z niego skorzystać, należy utworzyć obiekt odroczony w factory.confirmSave(), factory.confirmUpdate() i factory.confirmDelete(), zwróć obietnicę i rozwiąż / odrzuć ją w factory.confirm() i factory.cancel(). Gdy obietnica zostanie rozwiązana lub odrzucona, możesz pobrać wartość z factory lub pobierz go bezpośrednio jako argument odpowiedniego wywołania zwrotnego.

fabryka

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

kontroler

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

Pełny przykład patrz poniżej plunker.