sourcecode

각 서비스 함수에 $scope 삽입()

copyscript 2023. 4. 4. 21:57
반응형

각 서비스 함수에 $scope 삽입()

서비스 대상:

angular.module('cfd')
  .service('StudentService', [ '$http',
    function ($http) {
    // get some data via the $http
    var path = 'data/people/students.json';
    var students = $http.get(path).then(function (resp) {
      return resp.data;
    });     
    //save method create a new student if not already exists
    //else update the existing object
    this.save = function (student) {
      if (student.id == null) {
        //if this is new student, add it in students array
        $scope.students.push(student);
      } else {
        //for existing student, find this student using id
        //and update it.
        for (i in students) {
          if (students[i].id == student.id) {
            students[i] = student;
          }
        }
      }
    };

내가 전화했을 때save()$scope 을 얻습니다.ReferenceError: $scope is not defined ( 논리적인 순서는 save에 "save()"를 것입니다$scope그리고, 그 때문에, 그것을 / 에 제공/주입사해야 합니다.service이렇게 하면

  .service('StudentService', [ '$http', '$scope',
                      function ($http, $scope) {

다음의 에러가 표시됩니다.

오류: [$injector:unpr] 알 수 없는 공급자: $scopeProvider <- $scope <- Student Service

에러내의 링크(wow that neat!)는, 그것이 인젝터에 관련하는 것으로, js 파일의 선언 순서와 관계가 있는 것을 알 수 있습니다.재주문을 시도했습니다.index.html하지만 주입하는 방법 등 좀 더 간단한 것 같아요.

Angular-UI 및 Angular-UI 라우터 사용

$scope컨트롤러에 주입되는 것은 (주입 가능한 기타 물질과 같은) 서비스가 아니라 Scope 객체입니다.많은 스코프 객체를 만들 수 있습니다(일반적으로 상위 스코프에서 프로토타입으로 상속됨).는 " " " 입니다.$rootScope 해서 새로 수 요.$new()(「」를 한다)$rootScope

스코프의 목적은 앱의 프레젠테이션과 비즈니스 로직을 "접합"하는 것입니다.하는 것은 가 없다$scope서비스를 제공하게 됩니다.

서비스는 데이터를 공유하기 위해(예를 들어, 여러 컨트롤러 간에) 사용되는 단일 개체로, 일반적으로 재사용 가능한 코드 조각을 캡슐화합니다(컨트롤러, 디렉티브, 필터, 기타 서비스 등 필요한 앱의 모든 부분에 "서비스"를 주입하여 제공할 수 있기 때문입니다).

여러 가지 방법이 도움이 될 거라고 확신해요.을 사용하다
★★★★★★★★★★★★★★★★★.StudentService.StudentService 있는 예: 당신의 러러명명명명명명 keep keep keep((((((((((((((((((((((((((((((:$scope그 외의 뷰/컨트롤러/필터/서비스가 그 정보에 액세스 할 필요가 있는 경우(지금 당장 액세스 할 수 없는 경우라도, 이러한 정보가 표시되기 시작해도 놀라지 말아 주세요).
의 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★)save()방법)은 서비스 자체의 학생 배열이 갱신되고 해당 배열의 다른 모든 개체 공유도 자동으로 갱신됩니다.

상기의 어프로치에 근거해, 코드는 다음과 같습니다.

angular.
  module('cfd', []).

  factory('StudentService', ['$http', '$q', function ($http, $q) {
    var path = 'data/people/students.json';
    var students = [];

    // In the real app, instead of just updating the students array
    // (which will be probably already done from the controller)
    // this method should send the student data to the server and
    // wait for a response.
    // This method returns a promise to emulate what would happen 
    // when actually communicating with the server.
    var save = function (student) {
      if (student.id === null) {
        students.push(student);
      } else {
        for (var i = 0; i < students.length; i++) {
          if (students[i].id === student.id) {
            students[i] = student;
            break;
          }
        }
      }

      return $q.resolve(student);
    };

    // Populate the students array with students from the server.
    $http.get(path).then(function (response) {
      response.data.forEach(function (student) {
        students.push(student);
      });
    });

    return {
      students: students,
      save: save
    };     
  }]).

  controller('someCtrl', ['$scope', 'StudentService', 
    function ($scope, StudentService) {
      $scope.students = StudentService.students;
      $scope.saveStudent = function (student) {
        // Do some $scope-specific stuff...

        // Do the actual saving using the StudentService.
        // Once the operation is completed, the $scope's `students`
        // array will be automatically updated, since it references
        // the StudentService's `students` array.
        StudentService.save(student).then(function () {
          // Do some more $scope-specific stuff, 
          // e.g. show a notification.
        }, function (err) {
          // Handle the error.
        });
      };
    }
]);

이 방법을 사용할 때 주의해야 할 점은 서비스의 어레이를 재할당하지 않는 것입니다.이 경우 다른 컴포넌트(스코프 등)는 원래 어레이를 계속 참조하고 있기 때문에 어플리케이션이 중단됩니다.
예를 들어 어레이를 클리어하려면StudentService

/* DON'T DO THAT   */  
var clear = function () { students = []; }

/* DO THIS INSTEAD */  
var clear = function () { students.splice(0, students.length); }

짧은 데모도 보세요.


작은 업데이트:

중 할 수 몇 말. 단, 서비스 시 .service()★★★★★★ 。

관한 문서를 인용합니다.

Angular 서비스는 서비스 팩토리에 의해 작성된 싱글톤 객체입니다.이러한 서비스 팩토리는 서비스 프로바이더에 의해 만들어지는 기능입니다.서비스 공급자는 컨스트럭터 함수입니다.인스턴스화된 경우 다음과 같은 속성을 포함해야 합니다.$get서비스 팩토리 기능을 유지합니다.
[...]
...$provide프로바이더를 하지 않고 .「 」 。

  • provider(previder) - $devider를 사용하여 서비스 공급자를 등록합니다.
  • constant(obj) - 공급자 및 서비스에서 액세스할 수 있는 값/개체를 등록합니다.
  • value(obj) - 프로바이더가 아닌 서비스에서만 액세스할 수 있는 값/개체를 등록합니다.
  • factory (fn) - 서비스 팩토리 함수 fn을 등록합니다.이 함수는 서비스 공급자오브젝트로 래핑되며 $get 속성에 지정된 팩토리 함수가 포함됩니다.
  • service(class) - 서비스 공급자 개체로 래핑되는 생성자 함수($get 속성이 지정된 생성자 함수를 사용하여 새 개체를 인스턴스화하는 클래스)를 등록합니다.

기본적으로, 모든 Angular 서비스는 다음을 사용하여 등록됩니다.$provide.provider() 보다 간단한 '' , '접근' 방식, '접근' 방식, '접근' 방식, '접근' 방식, '접근' 방식, '접근' 방식 이 있습니다.service() ★★★★★★★★★★★★★★★★★」factory()를 참조해 주세요.
이 모든 것이 서비스로 "소모"되기 때문에 어떤 방법을 사용하든 큰 차이는 없습니다(그 방법으로 서비스 요건을 충족할 수 있는 한).

★★★★★★★★★★★★★★★★★★★★★」provider »service »factory 져서 찾아보세요 ( 검색해 보세요을 사용하다

(이것으로 해결되길 바랍니다. 해결되지 않으면 알려주세요.)

하려고 하지 요.$scope에서는 '실행하다', '하다', '실행하다'를 할 수 있습니다.$watch한 후 의 을 합니다.$scope다음은 컨트롤러에서 시도할 수 있는 예입니다.

angular.module('cfd')
    .controller('MyController', ['$scope', 'StudentService', function ($scope, StudentService) {

        $scope.students = null;

        (function () {
            $scope.$watch(function () {
                return StudentService.students;
            }, function (newVal, oldVal) {
                if ( newValue !== oldValue ) {
                    $scope.students = newVal;
                }
            });
        }());
    }]);

한 가지 주의할 점은 서비스 내에서 다음 작업을 수행하기 위해students "서비스" 오브젝트에 .this다음과 같이 합니다.

this.students = $http.get(path).then(function (resp) {
  return resp.data;
});

음 (긴 시간) ... 당신이 굳이 원한다면$scope을 사용하다

getter/setter 서비스 생성

ngapp.factory('Scopes', function (){
  var mem = {};
  return {
    store: function (key, value) { mem[key] = value; },
    get: function (key) { return mem[key]; }
  };
});

주입하여 컨트롤러 스코프를 저장합니다.

ngapp.controller('myCtrl', ['$scope', 'Scopes', function($scope, Scopes) {
  Scopes.store('myCtrl', $scope);
}]);

이제 다른 서비스 내에서 스코프를 가져옵니다.

ngapp.factory('getRoute', ['Scopes', '$http', function(Scopes, $http){
  // there you are
  var $scope = Scopes.get('myCtrl');
}]);

서비스는 싱글톤이며 스코프가 서비스에 삽입되는 것은 논리적이지 않습니다(실제로 스코프를 서비스에 삽입할 수 없습니다).범위를 매개 변수로 전달할 수도 있지만 여러 곳에서 범위가 편집되어 디버깅이 어려워지기 때문에 이 또한 잘못된 설계 선택입니다.스코프 변수를 처리하기 위한 코드는 컨트롤러로 전송되어야 하며 서비스 콜은 서비스로 전송되어야 합니다.

서비스에서는 범위를 전혀 인식하지 못할 수 있지만 컨트롤러에서는 범위를 비동기적으로 업데이트할 수 있습니다.

문제가 발생하고 있는 것은 HTTP 콜이 비동기적으로 발신되고 있는 것을 인식하고 있지 않기 때문입니다.즉, 값을 즉시 취득할 수 없습니다.예를 들어.

var students = $http.get(path).then(function (resp) {
  return resp.data;
}); // then() returns a promise object, not resp.data

이를 회피하는 간단한 방법은 콜백 기능을 제공하는 것입니다.

.service('StudentService', [ '$http',
    function ($http) {
    // get some data via the $http
    var path = '/students';

    //save method create a new student if not already exists
    //else update the existing object
    this.save = function (student, doneCallback) {
      $http.post(
        path, 
        {
          params: {
            student: student
          }
        }
      )
      .then(function (resp) {
        doneCallback(resp.data); // when the async http call is done, execute the callback
      });  
    }
.controller('StudentSaveController', ['$scope', 'StudentService', function ($scope, StudentService) {
  $scope.saveUser = function (user) {
    StudentService.save(user, function (data) {
      $scope.message = data; // I'm assuming data is a string error returned from your REST API
    })
  }
}]);

폼:

<div class="form-message">{{message}}</div>

<div ng-controller="StudentSaveController">
  <form novalidate class="simple-form">
    Name: <input type="text" ng-model="user.name" /><br />
    E-mail: <input type="email" ng-model="user.email" /><br />
    Gender: <input type="radio" ng-model="user.gender" value="male" />male
    <input type="radio" ng-model="user.gender" value="female" />female<br />
    <input type="button" ng-click="reset()" value="Reset" />
    <input type="submit" ng-click="saveUser(user)" value="Save" />
  </form>
</div>

이것에 의해, 간결성을 위해서 비즈니스 로직의 일부가 삭제되었습니다.실제로 코드를 테스트한 적은 없지만, 이와 같은 것이 유효합니다.주된 개념은 컨트롤러에서 나중에 호출되는 서비스로 콜백을 전달하는 것입니다.노드를 잘 알고 있는 경우JS 이것은 같은 개념입니다.

같은 곤경에 빠졌어요.나는 다음과 같이 결론지었습니다.여기서는 scope 객체를 공장에 주입하는 것이 아니라 $http 서비스에서 반환되는 약속 개념을 사용하여 컨트롤러 자체에 $scope를 설정합니다.

(function () {
    getDataFactory = function ($http)
    {
        return {
            callWebApi: function (reqData)
            {
                var dataTemp = {
                    Page: 1, Take: 10,
                    PropName: 'Id', SortOrder: 'Asc'
                };

                return $http({
                    method: 'GET',
                    url: '/api/PatientCategoryApi/PatCat',
                    params: dataTemp, // Parameters to pass to external service
                    headers: { 'Content-Type': 'application/Json' }
                })                
            }
        }
    }
    patientCategoryController = function ($scope, getDataFactory) {
        alert('Hare');
        var promise = getDataFactory.callWebApi('someDataToPass');
        promise.then(
            function successCallback(response) {
                alert(JSON.stringify(response.data));
                // Set this response data to scope to use it in UI
                $scope.gridOptions.data = response.data.Collection;
            }, function errorCallback(response) {
                alert('Some problem while fetching data!!');
            });
    }
    patientCategoryController.$inject = ['$scope', 'getDataFactory'];
    getDataFactory.$inject = ['$http'];
    angular.module('demoApp', []);
    angular.module('demoApp').controller('patientCategoryController', patientCategoryController);
    angular.module('demoApp').factory('getDataFactory', getDataFactory);    
}());

스코프 변수를 처리하기 위한 코드는 컨트롤러로 전송되어야 하며 서비스 콜은 서비스로 전송되어야 합니다.

요.$rootScope사용할 목적으로$rootScope.$broadcast ★★★★★★★★★★★★★★★★★」$rootScope.$on.

않으면 ""를 삽입하지 .$rootScope를 참조해 주세요

언급URL : https://stackoverflow.com/questions/22898927/injecting-scope-into-an-angular-service-function

반응형