2014-12-14 4 views
3

그래서 글로벌 메시지를 출력하는 지시문을 만들고 싶습니다. 지침의"App-Wide"메시지 시스템 작성하기

요구 ...

  1. 이 지시 메시지가 어떤 컨트롤러에서 업데이트 할 수 있습니다.

  2. 메시지가 모든 컨트롤러에서 업데이트 될 때 지시문도 결과적으로보기입니다. 뷰가

을 destoryed있다

  • 명확한 메시지 이후 지금까지 나는 함께 작업 지시문과 서비스를 만들어이 일을하고있다. 문제는 메시지가 다른 컨트롤러 내부에서 업데이트 될 때보기를 업데이트 할 수 없습니다.

    누군가가 계속 진행하는 방법을 알려주면 부풀어 오를 수 있습니다. $ rootScope를 사용하고 방송하는 것은 어떨까요?

    app.directive("alertMsg", ['MsgService', function(MsgService) { 
         return { 
          restrict: "E", 
          scope: true, 
          template: '{{msg}}', // this string is the html that will be placed inside the <alert-msg></alert-msg> tags. 
          link: function (scope, $element, attrs) { 
           scope.msg = MsgService.getAlertMsg(); //set msg to be available to the template above <alert-msg>{{msg}}</alert-msg> 
           scope.$on("$destroy", function(){ //when the <alert-msg> view is destroyed clear the alert message 
            MsgService.clearAlertMsg(); 
           }); 
          } 
         }; 
        }]);  
    
    
    app.service('MsgService', function() { 
           this.alertMsg = ''; 
           this.getAlertMsg = function(){ 
            return this.alertMsg; 
           }; 
           this.setAlertMsg = function(string) { 
            this.alertMsg = string; 
           }; 
           this.clearAlertMsg = function(){ 
            this.alertMsg = ''; 
           }; 
          }); 
    
    
    app.controller('NewPlateController', ['urlConfig', '$scope', '$http', '$location', 'MsgService', '$routeParams', function(urlConfig, $scope, $http, $location, MsgService, $routeParams) { 
         $scope.plate = {license_plate: $routeParams.plate, state: 'default-state'}; 
         // create new plate via json request 
         $scope.createPlate = function(){ 
          $http.post(urlConfig.rootUrl+"/plates.js", $scope.plate).success(function(data) { 
           $scope.plateInfo = data; 
           MsgService.setAlertMsg('Plate Sucessfully Created'); //Need to update the directive to actual show this update 
           $location.path('/plate/'+$scope.plateInfo.plate_id); 
          // http error: display error messages 
          }).error(function(data,status,headers,config) { 
           $scope.errors = data; 
           $('#new-plate-errors').slideDown('fast'); 
          }); 
         }; 
        }]); 
    
  • +1

    $ rootScope와 방송의 아이디어가 좋다고 생각합니다. – Kolban

    +0

    $ rootScope를 사용하는 것이 더 쉽고 깨끗하다고 ​​생각했습니다. Im impliment하는 방법은 확실하지 않습니다. 나는 지시를 사용하지만 서비스는 사용하지 않을 것인가? – JerryA

    답변

    1

    사용 $의 rootscope. $는 컨트롤러 (심지어 서비스) 및 사용 $의 rootScope에서 메시지를 보낼 방출한다. $에 당신의 지시에를받을 수 있습니다.

    지시문의 범위가 파손되면 수신기를 제거해야합니다. 그렇지 않으면 메모리 누수가 발생합니다.

    app.directive("alertMsg", ['$rootScope', function($rootScope) { 
        return { 
         restrict: "E", 
         scope: true, 
         template: '{{msg}}', // this string is the html that will be placed inside the <alert-msg></alert-msg> tags. 
         link: function (scope, $element, attrs) { 
          var _unregister; // store a reference to the message event listener so it can be destroyed. 
    
          _unregister = $rootScope.$on('message-event', function (event, message) { 
           scope.msg = message; // message can be value, an object, or an accessor function; whatever meets your needs. 
          }); 
    
          scope.$on("$destroy", _unregister) //when the <alert-msg> view is destroyed remove the $rootScope event listener. 
         } 
        }; 
    }]); 
    
    app.controller('NewPlateController', ['urlConfig', '$scope', '$http', '$location', '$rootScope', '$routeParams', function(urlConfig, $scope, $http, $location, $rootScope, $routeParams) { 
        $scope.plate = {license_plate: $routeParams.plate, state: 'default-state'}; 
        // create new plate via json request 
        $scope.createPlate = function(){ 
         $http.post(urlConfig.rootUrl+"/plates.js", $scope.plate).success(function(data) { 
          $scope.plateInfo = data; 
          $rootScope.$emit('message-event', 'Plate Sucessfully Created'); //use $emit, not $broadcast. Only $rootscope listeners are called. 
    
          scope.$on("$destroy", function() { // remove the message when the view is destroyed. 
           $rootScope.$emit('message-event', ""); 
          }); 
    
          $location.path('/plate/'+$scope.plateInfo.plate_id); 
         // http error: display error messages 
         }).error(function(data,status,headers,config) { 
          $scope.errors = data; 
          $('#new-plate-errors').slideDown('fast'); 
         }); 
        }; 
    }]); 
    

    메시지는 지시문 외부에서 유지되지 않으므로 범위가 삭제 될 때 메시지가 제거됩니다.

    편집 : 작동하는 예를 보여주는 JSFiddle 추가 : http://jsfiddle.net/kadm3zah/

    편집 2 : 내가보기가 파괴 될 때 메시지가 추가 제거 제거 할 수있는 요구 사항을 놓쳤다. 이 메서드를 사용하면 빈 문자열 메시지를 사용하여 NewPlateController 범위를 파괴 한 메시지에 두 번째 방사를 추가 할 수 있습니다.

    DOM에 지시문을 동적으로 추가하거나 제거하는 것은 포함되지 않습니다. 이를 위해 서비스를 사용하여 지시문 태그를 추가하고 나중에 제거 할 수 있습니다. 이것은 ngToast와 ui.boostrap의 모달 서비스가 작동하는 방식입니다. 그 중 하나를 사용하면 성취하고자하는 것에 더 적합 할 수 있습니다.

    +0

    당신이 제공 한 것과 똑같은 일을했지만 아직 메시지가 나타나지 않으며 콘솔에 오류가 없습니다. 내가 알아낼 수 있는지 알아 보자. – JerryA

    +1

    방출을 실행하기 위해 http 호출이 성공적으로 반환됩니까? 경고 지시문이 이미 페이지에 존재합니까? 아니면 경고가 표시 될 때 동적으로 추가하려고합니까? 팝업 메시지와 같은 경고를 동적으로 표시하려면 토스트 알림을 사용하십시오. [link] (http://tameraydin.github.io/ngToast/)는 그것을 성취하는 방법입니다. – meticoeus

    +0

    예, 기본 레이아웃과 템플릿에서 지침을 시도했습니다. 또한, 나는 여러 장소에서 방출했다. Console.log()는 링크 함수 내에서 실행되지 않습니다. 루트 범위에서 이미 트를 사용하여 루트 범위에서 시계를 트리거 할 수 있습니까? – JerryA

    관련 문제