angularjs asp.net-web-api angularjs-directive angularjs-scope angular-bootstrap

Cómo actualizar la página después de llamar al servicio $ http.put en la directiva que utiliza AngularJS/API web/Angular-ui-enrutador



ng-bind-html angular 5 (3)

Por favor, prueba los siguientes pasos:

1. Crea un método en la directiva svgFloorplanPopover y llámalo pasando los datos

En su directiva svgFloorplanPopover , agregue el elementoDataUpdate en la declaración del alcance:

... scope: { ''person'': ''=svgFloorplanPopover'', onDataUpdate: ''&'' } ...

y cuando intenta volver a cargar el estado, en lugar de volver a cargar el estado o la página, llame al código siguiente. Esto es para crear un sistema de eventos que se active desde dentro de la directiva para que el controlador o la directiva principal sepan que los datos han cambiado y que la vista ahora puede actualizarse.

$scope.onDataUpdate({person: $scope.person, moreData: $scope.moreData});

2. Cree un método en svgFloorplan para aceptar los datos pasados

Dado que usa un enfoque de directiva anidada, deberá usar el siguiente código en la directiva svgFloorplan .

group.setAttribute(''svg-floorplan-popover'', datasetBinding); group.setAttribute(''on-data-update'', onDataUpdateInController);

on-data-update corresponde al elemento svgFloorplanPopover el alcance de svgFloorplanPopover .

Declare el método onDataUpdateInController en el alcance de la directiva svgFloorplan .

scope.onDataUpdateInController = function(person, moreData) {};

Las propiedades del objeto que pasa desde dentro de la directiva se presentan planas para la cantidad de parámetros.

Si necesita pasar esta información más adelante a su controlador donde se declara svgFloorplan . Repita los dos pasos anteriores para la directiva svgFloorplan .

Espero que este enfoque sea claro. No es diferente de lo que se explica en Directivas angulares , sección Creación de una directiva que envuelve otros elementos y código donde se agrega un botón de cerrar. Aquí está el enlace directo al código en plunkr .

Solo una pregunta: ¿Usará estas directivas por separado? Si no, puede intentar crear una directiva en lugar de hacerlas dos. Esto reducirá la complejidad.

Somos nuevos en AngularJS pero estamos trabajando en una aplicación AngularJS / Web API que actualiza un modelo de datos de un popover / directivo de AngularJS Bootstrap .

Hemos actualizado con éxito la base de datos de la directiva / popover, sin embargo, tenemos problemas para averiguar cómo actualizar los datos en la página con los datos actualizados sin volver a cargar la página.

Página principal CSHTML:

<div ng-app="FFPA" ng-controller="myCtrl"> <div svg-floorplan="dataset"></div> </div>

Popover HTML:

<div> <div> ID: {{ person.Id }}<br /> Name: {{ person.fullName }}<br /> Current Cube/Office: {{ person.seatId }} <br /> Dept: {{ person.deptId }} <br /> Job Desc: {{ person.jobDesc}} <br /> Phone:{{ person.phone}} <br /> <!--<input type="button" value="Click Me" ng-click="changeName()">--> </div> <div class="hiddenDiv" ng-hide="toggle"> <div class="form-group"> <label for="floor">Floor</label> <input id="floor" ng-model="person.floor" type="text" ng-trim="true" class="form-control" /> </div> <div class="form-group"> <label for="section">Section</label> <input id="section" ng-model="person.section" ng-trim="true" type="text" class="form-control" /> </div> <div class="form-group"> <label for="offCubeNum">offCubeNum</label> <input id="offCubeNum" ng-model="person.offCubeNum" ng-trim="true" type="text" class="form-control" /> </div> <div class="form-group"> <label for="cbCube">Cubicle?</label> <input id="cbCube" ng-model="person.cbCube" type="checkbox" size="1" class="checkbox" /> </div> </div> <div ng-hide="buttonToggle"> <input type="button" value="Move" class="btn btn-success" ng-click="moveEmp()"> <input type="button" value="Term" class="btn btn-danger" ng-click="changeName()"> </div> <div ng-hide="submitToggle"> <input type="button" value="Submit" class="btn btn-success" ng-click="submitMove()"> <input type="button" value="Cancel" class="btn btn-warning" ng-click="cancel()"> </div> </div>

La página principal recibe inicialmente datos de un servicio en el controlador angular:

var app = angular.module(''FFPA'', [''ngAnimate'', ''ngSanitize'', ''ui.bootstrap'', ''ui.router'']); app.controller(''myCtrl'', function ($scope, dataService) { $scope.test = ''test''; dataService.getData().then(function (data) { //The reduce() method reduces the array to a single value. $scope.dataset = data.reduce(function (obj, item) { obj[item.seatId.trim()] = item; item.fullName = item.fName + '' '' + item.lName; item.deptId = item.deptId; item.jobDesc = item.jobDesc; item.phone = item.phone; return obj; }, {}); }); });

Obtener servicio de datos:

angular.module(''FFPA'').service(''dataService'', function ($http) { this.getData = function () { //web api call return $http.get("api/Controller/GetData).then( function (response) { return response.data; }, function () { return { err: "could not get data" }; } ); } });

El Servicio de actualización se llama desde la Directiva Popover.

Servicio de actualización:

angular.module(''FFPA'').service(''updateService'', function ($http) { this.putData = function (oc) { //web api call return $http.put("api/Controller/PutUpdateData", oc).then( function (response) { return response.data; }, function () { return { err: "could not update data" }; } ); } });

Aquí hay un fragmento de nuestra directiva Popover donde ocurre la actualización y donde pensamos que podríamos actualizar el alcance y los datos de la página:

updateService.putData(data).then(function (response) { if (response == false) alert("Move Failed!"); else { alert("Move Succeeded."); //$window.location.reload() causes a page reload..not desirable //$window.location.reload(); $state.reload(); } });

Probamos un $ state.reload (); en la directiva popover justo después de updateService.putData (data), sin embargo esto causó -> Error: No se puede pasar al estado abstracto ''Objeto object'' ''error.

Aquí está la Directiva completa de Popover:

angular.module(''FFPA'').directive(''svgFloorplanPopover'', [''$compile'', ''updateService'', ''vacancyService'', ''addService'', ''terminateService'', ''$window'', ''$state'', function ($compile, updateService, vacancyService, addService, terminateService, $window, $state) { return { restrict: ''A'', scope: { ''person'': ''=svgFloorplanPopover'', //UPDATE 8-MAY-2017 onDataUpdate: ''&'' }, link: function (scope, element, attrs) { scope.moveToggle = true; //hide move toggle scope.addToggle = true; //hide add toggle scope.submitToggle = true; //hide submit toggle scope.$watch("person", function () { if (scope.person) { if (scope.person.vacant == true) { scope.addToggle = false; //show add button scope.empInfoToggle = true; //hide emp info } else scope.moveToggle = false; //show move } }); //add employee--------------------------------------------------------- scope.addEmp = function () { scope.addToggle = scope.addToggle === false ? true : false; scope.buttonToggle = true; scope.submitToggle = false; var data = { deptId: scope.person.deptId, divisionId: scope.person.divisionId, empId: scope.person.empId, floor: scope.person.floor, fName: scope.person.fName, lName: scope.person.lName, jobDesc: scope.person.jobDesc, officeCode: scope.person.officeCode, phone: scope.person.phone, section: scope.person.section, seat: scope.person.seat, seatId: scope.person.seatId, seatTypeId: scope.person.seatTypeId, vacant: scope.person.vacant }; //call to update/move the employee //updateService.putData(scope.person).then(function () { addService.putData(data).then(function (response) { if (response == false) alert("Create Failed!"); else { alert("Create Succeeded."); //UPDATE 8-MAY-2017 $scope.onDataUpdate({ person: $scope.person, moreData: $scope.moreData }); //$window.location.reload(); //$route.reload(); //scope.toggle = false; } }); } //cancel function--------------------------------------------------------- scope.cancel = function () {} //Term emp--------------------------------------------------------- scope.termEmp = function () { var data = { seatId: scope.person.seatId, floor: scope.person.floor }; terminateService.putData(data).then(function (response) { if (response == false) alert("Term Failed!"); else { alert("Term Succeeded."); $window.location.reload(); //$route.reload(); //scope.toggle = false; } }); } //move employee--------------------------------------------------------- scope.moveEmp = function () { scope.toggle = scope.toggle === false ? true : false; scope.buttonToggle = true; scope.submitToggle = false; if (scope.person && scope.person.fullName.indexOf(''changed'') === -1) { //scope.person.fullName += '' move?''; } //Json object to send to controller to check for vacancy var data = { floor: scope.person.floor, section: scope.person.section, seat: scope.person.offCubeNum }; //can''t send object via $http.get (?) stringigy json and cast to Office object in controller. var json = JSON.stringify(data); //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //CHECK VACANCY service call //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vacancyService.getData(json) .then(function (response) { if (response == false) alert("cube/office occupied"); else{ //+++++++++++++++++++++++++++++++++++++++++++ //UPDATE service call //+++++++++++++++++++++++++++++++++++++++++++ //CONSTS var CONSTFLOORPREFIX = "f"; var CONSTSEAT = "s"; var CONSTC = "c" var floor = scope.person.floor; var section = scope.person.section; var offCube = scope.person.offCubeNum; scope.person.oldSeatId = scope.person.seatId; var newOfficeId = CONSTFLOORPREFIX + floor + CONSTSEAT; //f3s //IF CUBE if (scope.person.cbCube) { var trimSection = section.trim(); newOfficeId += trimSection + CONSTC; //f3s313c var trimOffCube = offCube.trim(); newOfficeId += trimOffCube; } else { newOfficeId += 0 + CONSTC + section; //f3s0c } scope.person.seatId = newOfficeId; //Json object to send to controller to check for vacancy var data = { Id: scope.person.Id, seatId: scope.person.seatId, oldSeatId: scope.person.oldSeatId, empId: scope.person.empId, lName: scope.person.lName, fName: scope.person.fName, refacName: scope.person.refacName, deptId: scope.person.deptId, divisionId: scope.person.divisionId, jobDesc: scope.person.jobDesc, seatTypeId: scope.person.seatTypeId, officeCode: scope.person.officeCode, phone: scope.person.phone, floor: scope.person.floor, section: scope.person.section, seat: scope.person.seat, vacant: scope.person.vacant }; //call to update/move the employee //updateService.putData(scope.person).then(function () { updateService.putData(data).then(function (response) { if (response == false) alert("Move Failed!"); else { alert("Move Succeeded."); //$window.location.reload(); $state.reload(); //$route.reload(); //scope.toggle = false; } }); }//end else }); } if (element[0].querySelector(''text'') != null){ scope.htmlPopover = ''./HTML/popoverTemplate.html''; element[0].setAttribute(''uib-popover-template'', "htmlPopover"); element[0].setAttribute(''popover-append-to-body'', ''true''); element[0].setAttribute(''popover-trigger'', "''click''"); //element[0].setAttribute(''popover-trigger'', "''mouseenter''"); element[0].setAttribute(''popover-placement'', ''right''); element[0].removeAttribute(''svg-floorplan-popover''); $compile(element)(scope); } } } }]);

ACTUALIZADO: 8-MAYO-2017 Originalmente, hay un servicio de datos adicional y una directiva que dejamos fuera de esta publicación, ya que puede considerarse información no esencial, aunque se haya agregado recientemente, ya que puede ser necesaria.

Directiva de carga SVG:

angular.module(''FFPA'').directive(''svgFloorplan'', [''$compile'', function ($compile) { return { restrict: ''A'', //restrict attributes templateUrl: ''./SVG/HQ3RD-FLOOR3v10.svg'', scope: { ''dataset'': ''=svgFloorplan'' }, link: { pre: function (scope, element, attrs) { //filter groups based on a cube/office id var groups = element[0].querySelectorAll("g[id^=''f3'']"); //groups.style("pointer-events", "all"); scope.changeName = function (groupId) { if (scope.dataset[groupId] && scope.dataset[groupId].lastName.indexOf(''changed'') === -1) { scope.dataset[groupId].lastName += '' changed''; } } groups.forEach(function (group) { var groupId = group.getAttribute(''id''); if (groupId) { //set vacancy colors on vacant cubes scope.$watch("dataset", function () { if (scope.dataset) { if (typeof scope.dataset[groupId] !== "undefined") { //vacant cubes and offices hover if (scope.dataset[groupId].vacant == true) { //seat type id 1 = cube if (scope.dataset[groupId].seatTypeId == 1){ d3.select(group).select("rect").style("fill", "#99ff33").style("opacity", 0.4) .style("pointer-events", "all") .on(''mouseover'', function () { d3.select(this).style(''opacity'', 0.9); }) .on(''mouseout'', function () { d3.select(this).style(''opacity'', 0.4); }) } //vacant office else { d3.select(group).select("path").style("stroke", "#ffffff").style("opacity", 1.0); d3.select(group).select("path").style("fill", "#99ff33").style("opacity", 0.4) .style("pointer-events", "all") .on(''mouseover'', function () { d3.select(this).style(''opacity'', 0.9); }) .on(''mouseout'', function () { d3.select(this).style(''opacity'', 0.4); }) } } else { //Occupied //seat type id 1 = cube if (scope.dataset[groupId].seatTypeId == 1) { d3.select(group).select("rect").style("fill", "#30445d").style("opacity", 0.0) .style("pointer-events", "all") .on(''mouseover'', function () { d3.select(this).style(''opacity'', 1.0); d3.select(group).select(''text'').style("fill", "#FFFFFF"); }) .on(''mouseout'', function () { d3.select(this).style(''opacity'', 0.0); d3.select(group).select(''text'').style("fill", "#000000"); }) //TODO: cubes have rects and on the north side of the building wall, paths. d3.select(group).select("path").style("fill", "#30445d").style("opacity", 0.0) .style("pointer-events", "all") .on(''mouseover'', function () { d3.select(this).style(''opacity'', 1.0); d3.select(group).select(''text'').style("fill", "#FFFFFF"); }) .on(''mouseout'', function () { d3.select(this).style(''opacity'', 0.0); d3.select(group).select(''text'').style("fill", "#000000"); }) } //occupied office else { //d3.select(group).select("path").style("stroke", "#ffffff").style("opacity", 0.8); d3.select(group).select("path").style("fill", "#5A8CC9").style("opacity", 1.0) .style("pointer-events", "all") .on(''mouseover'', function () { //alert("office"); d3.select(this).style("fill", "#2d4768").style(''opacity'', 1.0); d3.select(group).selectAll(''text'').style("fill", "#FFFFFF"); }) .on(''mouseout'', function () { d3.select(this).style("fill", "#5A8CC9").style(''opacity'', 1.0); d3.select(group).selectAll(''text'').style("fill", "#000000"); }) } }//end occupied else } } }); //UPDATE 8-MAY-2017->Implementation Question scope.onDataUpdateInController = function (person, moreData) { }; var datasetBinding = "dataset[''" + groupId + "'']"; group.setAttribute(''svg-floorplan-popover'', datasetBinding); //UPDATE 8-MAY-2017 //on-data-update corresponds to onDataUpdate item on svgFloorplanPopover''s scope. group.setAttribute(''on-data-update'', onDataUpdateInController); $compile(group)(scope); } }); } } } }]);

Servicio de vacantes (consultar antes de la actualización):

angular.module(''FFPA'').service(''vacancyService'', function ($http) { ... }

La pregunta principal es:

¿Cómo podemos hacer que nuestra aplicación actualice nuestra página con los datos actualizados sin volver a cargar la página?

Solíamos ser capaces de hacer esto en UpdatePanels en las formas web ASP.Net en el día. Creo que fueron postbacks parciales / llamadas AJAX ...

EDITADO 2-AGO-2017

+++++++++++++++++++++++++++++++++++

Aunque la recompensa se otorgó automáticamente, todavía no tenemos una respuesta a esta pregunta. Sin ningún contexto de implementación, las respuestas dadas no son útiles.

¿Alguien puede ampliar las respuestas dadas para darnos una idea de cómo se puede resolver este problema?

Gracias


Simplemente agregue sus datos en el objeto $scope y úselos en su vista, cada vez que actualice o modifique los datos, por ejemplo: considere que tiene una función para obtener los datos en los que realiza el resto llame a su base de datos

$scope.getdata=function(){ $http.get(url).success(function(data) { $scope.data=data; });

Cada vez que modifique sus datos solo llame a esta función en su caso al hacer clic en cerrar de directiva / emergente