2014-04-19 4 views
2

업데이트하려고하고 AngularJs 팩토리의 업데이트 값을 가져 오는 중 하나의 범위에서 값을 설정하고 다른 가져 오기 위해 애쓰는 대신 내 응용 프로그램에서 팝업 메시지를 처리하도록 팩터 리를 설정 중입니다. 내 자신을 되풀이하는 것은 단지 하나의 공장이 메시지를 다루기를 바란다.AngularJs 팩토리에서 업데이트 값을 가져올 수없는 이유는 무엇입니까?

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

사용자의 컨트롤러는

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

    } 

}); 

답변

1

당신이 제공 한 코드가 잘 작동 것으로 보인다 문제는 아마 cms 컨트롤러 또는 confirm.html 템플릿, 다른 곳이다. 공장에서 내가 살고있는 곳으로 plunker을 만들었습니다.

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> 

자바 스크립트

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

몇 가지 팁 :

  • 사용 var factory = {}; 대신 factory = {} 지역 변수를 선언하기 위해서가 아니라이 factory 때때로 글로벌 오버라이드 (override)합니다. 그들이
  • factory.setTextfacory.getResponse가 중복 쓸모가 있기 때문에 factory.textfactory.responsefactory의 공용 속성이기 때문에
  • factory.modal;factory.response;는, 그래서 그냥 제거, 예상대로 factory 객체에 관련된 속성을 선언 대신 undefined을 반환하지 않습니다 . 공장에서 비공개로 설정하려면 var text;var response;으로 신고하고 그에 따라 접근 자 메서드를 변경하십시오. 이 경우에 getText을 공장에 추가하는 것도 유용 할 것입니다.
  • 공장에서 factory.modal에만 액세스하려는 경우 이전 글 머리 기호에서 설명한대로 공장에 캡슐화하는 것이 좋습니다 (비공개로 설정하는 것이 좋습니다).
  • 는 공장은 다음과 같이 수있는 모든 팁을 적용하면

(예 : window 노출되지 않도록) 공장에서 공공의 API를 노출 :

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

plunker이다.

편집 : 당신이 컨트롤러 코드 모두에 게시물을 업데이트 나에게 분명하다 후

: 진짜 문제는 동 기적으로 confirmDelete()를 사용하지만, 그것은 미래의 반환 값 때문에 (비동기, 사용자가 확인 또는 취소를 클릭하면)! 비동기 직원을 다루기 위해서는 $q 서비스가 필요합니다. 이를 사용하려면 factory.confirmSave(), factory.confirmUpdate()factory.confirmDelete()에 지연된 객체를 생성하고 약속을 지키고 factory.confirm()factory.cancel()으로 해결/거부해야합니다. 약속이 해결되거나 거부되면 factory에서 값을 가져 오거나 관련 콜백의 인수로 직접 가져올 수 있습니다.

공장

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

컨트롤러

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

전체 예를 들어 다음과 같은 plunker에서 참조하십시오.

+0

잘 작동하지만 다른 컨트롤러에 문제가있는 것처럼 보입니다. anngularjs + foundatio를 사용하고 있으며 http://madmimi.github.io/angular-foundation/ modal 지시문을 사용하고 있습니다. , "CMS"콘트롤러는 모달 콘텐트를 보여줄뿐입니다. 저는 'msg'팩토리를 호출하고 다른 콘트롤러에 그것을 주입하고 응답을 시도합니다. 그래서 사용자가 확인하면 'msg'팩토리 '응답 '속성은'true '로 업데이트됩니다. 문제는 두 번째 클릭에서만 올바른 응답을 얻을 수 있다는 것입니다. , 업데이트 된 코드를 확인하십시오 – munzx

+0

@ munzx 마지막 편집을 참조하십시오. 문제의 근본 원인을 찾은 것 같습니다. – Vadim

+0

정말 고맙습니다. , 당신은 끝내 주셔서 감사합니다 다시 :) 감사합니다 – munzx