티스토리 뷰

반응형

 javascript에서 callback 함수에 관한 글 중에서 비동기 처리 방식에 관련하여 callback이 많이 사용된다는 것을 알았다.

나도 같은 경우가 발생되었다.


angluarjs로 사이트를 만들던 중 data-obejct 관련된 글을 보게 되었다.

http://www.webdeveasy.com/angularjs-data-model/


여기서 확인했을때 각 entity별로 crud 등을 수행 할 수 있도록 data-object 객체를 만들고 화면단에서는 해당 기능을 호출하는 방식으로 개발하도록 하는 방법이다.


아래 angularjs.factory를 이용하여 Book 의 Crud를 만들었다.


Book model service
app.factory('Book', ['$http', function($http) {  
    function Book(bookData) {
        if (bookData) {
            this.setData(bookData):
        }
        // Some other initializations related to book
    };
    Book.prototype = {
        setData: function(bookData) {
            angular.extend(this, bookData);
        },
        load: function(id) {
            var scope = this;
            $http.get('ourserver/books/' + bookId).success(function(bookData) {
                scope.setData(bookData);
            });
        },
        delete: function() {
            $http.delete('ourserver/books/' + bookId);
        },
        update: function() {
            $http.put('ourserver/books/' + bookId, this);
        },
        getImageUrl: function(width, height) {
            return 'our/image/service/' + this.book.id + '/' + width + '/' + height;
        },
        isAvailable: function() {
            if (!this.book.stores || this.book.stores.length === 0) {
                return false;
            }
            return this.book.stores.some(function(store) {
                return store.quantity > 0;
            });
        }
    };
    return Book;
}]);



그리고 controller에서 만들어진 service 객체를 가져와서 사용하는 부분이다.


BookController that uses Book model
app.controller('BookController', ['$scope', 'Book', function($scope, Book) {  
    $scope.book = new Book();
    $scope.book.load(1);
}]);



좀더 확장해서 기능을 구현할 때 문제가 발생되었다.


서비스 수정

app.factory('Book', ['$http', function($http) {  
    function Book(bookData) {
        if (bookData) {
            this.setData(bookData):
        }
        // Some other initializations related to book
    };
    Book.prototype = {
        setData: function(bookData) {
            angular.extend(this, bookData);
        },
        load: function(id) {
            var scope = this;
            $http.get('ourserver/books/' + bookId).success(function(bookData) {
                scope.setData(bookData);
            });
        },
        delete: function() {
            $http.delete('ourserver/books/' + bookId);
        },
        update: function() {
            $http.put('ourserver/books/' + bookId, this);
        },
        save : function (data) {  // save 펑션 추가
            $http.post('ourserver/books')
             .success(function(data){ 
                   this.setData(data);
             });
        }
        getImageUrl: function(width, height) {
            return 'our/image/service/' + this.book.id + '/' + width + '/' + height;
        },
        isAvailable: function() {
            if (!this.book.stores || this.book.stores.length === 0) {
                return false;
            }
            return this.book.stores.some(function(store) {
                return store.quantity > 0;
            });
        }
    };
    return Book;
}]);



컨트롤러 수정

app.controller('BookController', ['$scope', 'Book', function($scope, Book) {  
    $scope.book = new Book();
    $scope.book.load(1);
    // book 저장
    $scope.saveData = function (data) {
      $scope.book.save(data);
      $scope.data = $scope.book;
   }


}]);



Book 정보를 입력 후 서버에서 생성된 bookId 와 입력 한 정보를 Book 객체 안에서 setData 시킨 뒤


그 정보를 화면단 data에다가 넣어 줄려고 할때 발생되었다.


book 정보를 불러올 수 없게 된 것이다.



이유는 $scope.book.save() function을 호출하고 처리 후 데이터를 화면단 scope에 넣는 방식으로 되어야 하는데 이때 비동기적으로 data가 save 후 setData를 시킨다는 것을 간과한 것이다.


너무 절차적으로 코드를 작성하는 것에 익숙했다가 잠시 비동기적 처리가 추가되다보니 이런 문제가 발생된 것이다.


이때 좀더 생각을 할 수 있었으면 좋으련만 

친구가 도움을 준 방법으로 callback 방식으로 처리 할 수 있었다.


서비스 수정


app.factory('Book', ['$http'function($http) {
    function Book(bookData) {
        if (bookData) {
            this.setData(bookData):
        }
        // Some other initializations related to book
    };
    Book.prototype = {
        setData: function(bookData) {
            angular.extend(this, bookData);
        },
        load: function(id) {
            var scope = this;
            $http.get('ourserver/books/' + bookId).success(function(bookData) {
                scope.setData(bookData);
            });
        },
        delete: function() {
            $http.delete('ourserver/books/' + bookId);
        },
        update: function() {
            $http.put('ourserver/books/' + bookId, this);
        },
        save : function (data, callback) {  // save 펑션 추가, callback 함수 추가
            $http.post('ourserver/books')
             .success(function(data){ 
                   this.setData(data);
                   // 처리 후 callback 호출
                   callback();
             });
        }
        getImageUrl: function(width, height) {
            return 'our/image/service/' + this.book.id + '/' + width + '/' + height;
        },
        isAvailable: function() {
            if (!this.book.stores || this.book.stores.length === 0) {
                return false;
            }
            return this.book.stores.some(function(store) {
                return store.quantity > 0;
            });
        }
    };
    return Book;
}]);



컨트롤러 수정

 

app.controller('BookController', ['$scope''Book'function($scope, Book) {    
    $scope.book = new Book();
    $scope.book.load(1);
    // book 저장
    $scope.saveData = function (data) {
      $scope.book.save(data,function(){
        $scope.data = $scope.book;
     });
   }


}]);



간단하게 예제로 설명하였다. 저런 방식으로 비동기 처리 후 다음 절차를 callback 함수로 전달하여 처리 할 수 있도록 하면 되는 것이였다.






 

반응형