AngularJS/Web API/Angular-UI-Router का उपयोग करके डायरेक्टिव में $ http.put सेवा कॉल करने के बाद पेज अपडेट करने के लिए कैसे करें




asp.net-web-api angularjs-directive (3)

हम AngularJS के लिए नए हैं लेकिन एक AngularJS / वेब एपीआई अनुप्रयोग पर काम कर रहे हैं जो एंगुलर जेएस बूटस्ट्रैप पॉपओवर / डायरेक्टिव से एक डेटा मॉडल अपडेट करता है।

हमने डायरेक्टिव / पॉपओवर से डेटाबेस को सफलतापूर्वक अपडेट किया है, लेकिन पृष्ठ को फिर से लोड किए बिना अद्यतित डेटा के साथ पृष्ठ पर डेटा को रीफ्रेश करने का पता लगाने में समस्या हो रही है।

मुख्य पृष्ठ सीएसएचएमएल:

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

पॉपओवर 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>

मुख्य पृष्ठ शुरू में कोयोनर नियंत्रक में एक सेवा से डेटा प्राप्त होता है:

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;

            }, {});
        });
    });

डेटा सेवा प्राप्त करें:

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

अद्यतन सेवा को पॉपवर निर्देशक से कहा जाता है।

सेवा अद्यतन करें:

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

यहां हमारे पॉपोवर डायरेक्टिव से एक स्निपेट है जहां अपडेट होता है और जहां हमने सोचा था कि हम दायरे को रीफ्रेश कर सकते हैं, और पेज के लिए डेटा:

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

हमने एक $ राज्य की कोशिश की। रीलोड (); updateService.putData (डेटा) के बाद 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);
        }
    }
}
}]);

नवीनीकृत: 8-मई-2017 मूल रूप से एक अतिरिक्त डेटा सेवा और निर्देश है जो हमने इस पोस्ट से छोड़ा था क्योंकि इसे आवश्यक जानकारी नहीं माना जा सकता है, हालांकि हाल ही में जोड़ा गया क्योंकि इसकी आवश्यकता हो सकती है।

एसवीजी लोड डायरेक्टिव:

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


    }
}
}]);

रिक्ति सेवा (अद्यतन से पहले जांच करें):

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

मुख्य प्रश्न यह है:

पृष्ठ को पुनः लोड किए बिना हम अपडेट किए गए डेटा के साथ हमारे पेज को कैसे ताज़ा कर सकते हैं?

हम दिन में एएसपी.Net वेबफॉर्म में अपडेट पैनल्स में ऐसा करने में सक्षम थे। मुझे लगता है कि वे आंशिक पोस्टबैक / AJAX कॉल थे ..

संपादित 2-अगस्त -2017

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

यद्यपि दान को स्वचालित रूप से सम्मानित किया गया था, फिर भी हमारे पास इस प्रश्न का उत्तर नहीं है। बिना किसी कार्यान्वयन के संदर्भ दिए गए उत्तर उपयोगी नहीं हैं।

क्या कोई हमें इस समस्या को सुलझाने के बारे में एक विचार देने के लिए दिए गए उत्तरों पर विस्तार कर सकता है?

धन्यवाद


अपना दृश्य ताज़ा करने के लिए (प्राप्त डेटा बाँध न करें) निम्नलिखित प्रश्नों के उत्तर का उपयोग करें:

एनजीआरयूटीई मॉड्यूल का उपयोग करना AngularJS का उपयोग करके पूरे पृष्ठ को पुनः लोड या पुन: रेंडर कैसे करें

यूआई-राउटर मॉड्यूल का उपयोग करना वर्तमान स्थिति को पुनः लोड करना - ताज़ा डेटा

इसके साथ मैं आपको प्राप्त डेटा को अपने घिरी हुई दायरा संपत्ति के लिए आवंटित करने के लिए सुझाऊंगा।

आप एक अद्यतन plnkr प्रदान करने के बाद मैं एक पूर्ण उदाहरण जोड़ देंगे :)


कृपया निम्न चरणों का प्रयास करें:

1. svgFloorplanPopover डायरेक्टिव में एक विधि बनाएं और डेटा में पास करके इसे कॉल करें

अपने svgFloorplanPopover डायरेक्टिव में, स्कोप घोषणापत्र onDataUpdate आइटम को जोड़ें:

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

और जहां आप राज्य को पुनः लोड करने की बजाय राज्य को पुनः लोड करने की कोशिश कर रहे हैं, नीचे कोड को कॉल करें यह एक इवेंट सिस्टम बनाने के लिए है, जिसे डायरेक्टिव में से नियंत्रक या पैरेंट डायरेक्टिव को यह बताने के लिए कि डेटा बदल गया है और देखें अब अपडेट किया जा सकता है, निकाल दिया गया है।

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

2. पारित डेटा को स्वीकार करने के लिए svgFloorplan में एक विधि बनाएं

चूंकि आप नेस्टेड डायरेक्टिव दृष्टिकोण का उपयोग कर रहे हैं, आपको नीचे दिए गए कोड को svgFloorplan निर्देश में उपयोग करना होगा।

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

on-data-update svgFloorplanPopover के दायरे पर svgFloorplanPopover on-data-update आइटम से मेल खाती है।

svgFloorplan निर्देश के दायरे onDataUpdateInController विधि पर घोषणा करें।

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

ऑब्जेक्ट गुण जो आप निर्देश के भीतर से पास करते हैं, उन्हें पैरामीटर की संख्या के अनुसार फ्लैट रखा जाता है।

यदि आपको इस डेटा को अपने नियंत्रक तक आगे की आवश्यकता है जहां svgFloorplan घोषित किया गया है। svgFloorplan निर्देश के लिए ऊपर दिए गए दो चरणों को svgFloorplan

मुझे उम्मीद है कि यह दृष्टिकोण स्पष्ट है। यह कोणीय निर्देशों में समझाया गया है, उस से अलग नहीं है, अनुभाग एक निर्देशक का निर्माण करना जो कि अन्य तत्वों और कोड जहां एक करीबी बटन जोड़ा जाता है। यहां कोड के लिए सीधा लिंक है,

सिर्फ एक सवाल: क्या आप इन निर्देशों को एक-दूसरे से अलग से उपयोग करने जा रहे हैं? यदि नहीं, तो आप उन्हें दो बनाने के बजाय एक निर्देश बनाने का प्रयास कर सकते हैं। इससे जटिलता कम हो जाएगी


सिर्फ अपने डेटा को $scope ऑब्जेक्ट पर जोड़ें और अपने दृश्य में इसका उपयोग करें, जब भी आप डेटा को अपडेट या संशोधित करते हैं जैसे उदाहरण: आपके पास डेटा प्राप्त करने के लिए एक फ़ंक्शन है जहां आप अपने डीबी को बाकी कॉल कर रहे हैं

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

जब भी आप अपने डेटा को संशोधित करते हैं, तो बस इस फ़ंक्शन को अपने मामले में डायरेक्टिव / पॉपअप बंद होने पर क्लिक करें





angular-bootstrap