2013-03-25 3 views
8

jQuery 플러그인을 감싸는 지시문을 작성했으며 컨트롤러의 지시문을 컨트롤러에서 지시문으로 전달합니다. (작품)AngularJS의 컨트롤러 및 지시문 사이의 공유 범위

config 개체에서 나는 이벤트를 호출하고자하는 콜백입니다.

콜백에서 컨트롤러의 $ scope에있는 속성을 수정하고 싶습니다. 은 작동하지 않습니다.. Angular는 속성이 어떤 이유로 변경되었다는 것을 인식하지 못하기 때문에 콜백의 $ 범위가 컨트롤러의 $ 범위와 다를 수 있습니다. 제 문제는 제가 왜 그렇게하지 않는 것입니다.

아무도 올바른 방향으로 나를 가리킬 수 있습니까?


Click here for Fiddle


는 app.js

var app = angular.module('app', []) 
    .directive('datepicker', function() { 
     return { 
      restrict: 'A', 
      link: function (scope, element, attrs) { 
       // Uncommenting the line below causes 
       // the "date changed!" text to appear, 
       // as I expect it would. 
       // scope.dateChanged = true; 

       var dateInput = angular.element('.datepicker') 

       dateInput.datepicker(scope.datepickerOpts); 

       // The datepicker fires a changeDate event 
       // when a date is chosen. I want to execute the 
       // callback defined in a controller. 
       // --- 
       // PROBLEM: 
       // Angular does not recognize that $scope.dateChanged 
       // is changed in the callback. The view does not update. 
       dateInput.bind('changeDate', scope.onDateChange); 
      } 
     }; 
    }); 

var myModule = angular.module('myModule', ['app']) 
    .controller('MyCtrl', ['$scope', function ($scope) { 
     $scope.dateChanged = false; 

     $scope.datepickerOpts = { 
      autoclose: true, 
      format: 'mm-dd-yyyy' 
     }; 

     $scope.onDateChange = function() { 
      alert('onDateChange called!'); 

      // ------------------ 
      // PROBLEM AREA: 
      // This doesnt cause the "date changed!" text to show. 
      // ------------------ 
      $scope.dateChanged = true; 

      setTimeout(function() { 
       $scope.dateChanged = false; 
      }, 5000); 
     }; 
    }]); 

HTML

<div ng-controller="MyCtrl"> 
    <p ng-show="dateChanged">date changed!</p> 
    <input type="text" value="02-16-2012" class="datepicker" datepicker=""> 
</div> 

답변

11

은 데모에 직장에서 범위의 문제가 있습니다. 먼저 dateChange 콜백 내에서 함수 자체가 컨트롤러 내에서 선언 되더라도 콜백 내의 this 컨텍스트는 부트 스트랩 처리기 내에 있으므로 부트 스트랩 요소입니다.

제 3 자 코드에서 각도 범위 값을 변경할 때마다 각도는 $apply을 사용하여 각도에 대해 알아야합니다. 일반적으로 지시문 안에 모든 제 3 자 범위를 유지하는 것이 가장 좋습니다.

더 많은 각도의 접근은 입력에 ng-model을 사용하는 것입니다. 그런 다음 모델을 변경하려면 $.watch을 사용하십시오. 이렇게하면 각도 컨텍스트 내에서 컨트롤러 안의 모든 코드를 유지하는 데 도움이됩니다.어떤 형태에 ng-model를 사용하지 않는 어떤 각도 응용 프로그램에서 희귀 한 것은 지시어 내에서

<input type="text" class="datepicker" datepicker="" ng-model="myDate"> 

제어 :

컨트롤러에서 다음
dateInput.bind('changeDate',function(){ 
     scope.$apply(function(){ 
     scope[attrs.ngModel] = element.val() 
     }); 
}); 

:

$scope.$watch('myDate',function(oldVal,newVal){ 
     if(oldVal !=newVal){ 
      /* since this code is in angular context will work for the hide/show now*/ 
      $scope.dateChanged=true; 
      $timeout(function(){ 
        $scope.dateChanged=false; 
       },5000); 
     }   
}); 

데모 : http://jsfiddle.net/qxjck/10/

편집이 지시문을 페이지의 둘 이상의 요소에서 사용하려면 변경해야하는 항목이 하나 더 있습니다 (var dateInput = angular.element('.datepicker')). 그것은 element이 이미 link 콜백의 인수 중 하나이며 인스턴스에 따라 달라지는 지시문에 중복되어 사용됩니다. dateInputelement

+0

으로 한 번 더 바꾸십시오. github에서 사용하기 쉬운 몇 가지 각도/부트 스트랩 UI 지침 프로젝트가 있습니다. – charlietfl

+0

나를 똑바로 세워 줘서 고마워. 나는 $ apply를 사용하여 즉시 작업 할 수있게 만들었지 만, 당신이 보여준 접근 방식을 구현하려고 노력하고 있습니다. 내가 보여주지 않았지만 데모에서 가지고 있어야하는 것은 실제로 * * 태그를 사용하여 날짜 선택 도구를 시작한 것입니다. 선택된 날짜는'element.data ('datepicker'). getDate()'에 저장됩니다. AngularJS에 처음 왔으므로 틀렸을 경우 실례합니다.하지만 ng-model은 양식 요소 용입니다. 적절한 대체품은 무엇입니까? – simshaun

+0

jQuery Ui one과 마찬가지로 부트 스트랩 datepicker에 익숙하지 않습니다. 그러나 입력에서'ng-model'을 사용하는 대신 컨트롤러 범위에서 변수를 하드 코딩하거나 변수 이름을 저장할 사용자 정의 속성을 사용할 수 있습니다 (예 : 페이지의 여러 위치에서 사용). 더 많은 문제가 있으시면'' 태그 구현으로 업데이트 된 버전을 만드십시오. 지시어의'scope. $ apply' 호출에서 수정하기 쉬운 데이터의 값으로서의 소스. 동일한'$ watch' 방법론을 유지하십시오. – charlietfl

2

입력에 연결된 changeDate 이벤트가 각도 프레임 워크 외부에서 실행되도록 설정되어있는 것 같습니다. 단락을 표시하려면 dateChanged을 true로 설정 한 후 $scope.$apply()으로 전화하십시오. 지연 후 단락을 숨기려면 setTimeout에 전달 된 함수 내에서 $apply()을 다시 사용할 수 있지만 Angular의 $timeout()을 사용하면 문제가 계속 발생하지 않습니다.

Fiddle

관련 문제