2013-03-01 5 views
35

컨트롤러 기능에서 지시문의 속성에 액세스하려고합니다. 그러나, 내가 액세스 할 때까지 그것은 정의되지 않습니다. 나는 그것이 간단한 타이머를하면 작동하는 것으로 나타났습니다. 지시어와 스코프가 준비되고 사용되도록 설정된 후에 만 ​​코드를 실행하는 방법이 있습니까?AngularJS 지시문은 컨트롤러에서 액세스를 특성화합니다.

나는 그것으로 바이올린을 만들었습니다. 콘솔이 열려 있는지 확인하십시오. 여기

http://jsfiddle.net/paulocoelho/uKA2L/1/ 내가 바이올린에 사용하고있는 코드입니다 :

<div ng-app="testApp" > 
    <testcomponent text="hello!"></testcomponent> 
</div> 
당신은 연결과 제어 기능 내부

scope.text = $attrs.text; 

을 설정 한 경우입니다 작동 무엇

var module = angular.module('testApp', []) 
    .directive('testcomponent', function() { 
    return { 
     restrict: 'E', 
     template: '<div><p>{{text}} This will run fine! </p></div>', 
     scope: { 
      text: '@text' 
     }, 
     controller: function ($scope, $element) { 
      console.log($scope.text); // this will return undefined 
      setTimeout(function() { 
       console.log($scope.text); // this will return the actual value... 
      }, 1000); 
     }, 
     link: function ($scope, $element, $attrs) { 
      console.log($scope.text); 
      setTimeout(function() { 
       console.log($scope.text); 
      }, 1000); 
     } 
    }; 
}); 

답변

25

. 이것은 2way- 데이터 바인딩이 없기 때문에 처음에는 작동합니다. 그래도 $attrs.observe을 사용할 수 있습니다.

참조 바이올린 : 그 순간 범위 변수가 정의되지 않습니다에 http://jsfiddle.net/JohannesJo/nm3FL/2/

+0

응을, 나를 위해 작동합니다 :) 덕분에 남자 – PCoelho

+1

이 linting을 실패합니다. 'attrs.text'는 알려지지 않았기 때문에. –

+1

@DougChamberlain JSDoc을 사용하여이 문제를 해결할 수 있습니다. ''@param {string} attrs.text''와 같은 것이 여러분의 문제를 해결할 것입니다. –

1

링크 기능은 루프를 다이제스트 $ 전에 호출된다. 링크 기능의 작동 방식을 이해하려면 this chapterthis other을 확인하십시오. 지시어에 대한 시계 및/또는 동작을 정의하기 위해 링크 기능 만 사용하고 모델을 조작하지는 않습니다. 이것은 컨트롤러에서 수행됩니다.

+0

이것이 사실이 아닙니다. 범위 변수는 사후 링크 기능이 실행되는 시간으로 정의되며 링크 기능에서 데이터 모델을 조작하는 것이 좋습니다. 컨트롤러는 require 속성을 통해 다른 지시문과 통신하는 데 사용하려는 경우 지시문에만 필요합니다. 컨트롤러가 실제로 먼저 실행되고, pre-link가 이어지고, dom 트리를 따라 잎으로 가다가 루트로 포스트 링크됩니다. 설명을 위해이 스레드를 참조하십시오. https://stackoverflow.com/questions/24615103/angular-directives-when-and-how-to-use-compile-controller-pre-link-and-post –

23

격리 된 범위에서 '@'로 정의 된 로컬 범위 속성은 연결 기능에서 액세스 할 수 없습니다. @remigio가 이미 언급했듯이, 그 지역 범위 속성은 그 시점에 undefined입니다. $ attrs. $ observe() 또는 $ scope. (보간 된) 값을 비동기 적으로 얻으려면 $ watch()를 사용해야합니다.

속성에 상수 값을 전달하는 경우 (즉, 보간이 필요하지 않은 경우, 즉 속성 값에 {{}}이 (가) 포함되어 있지 않은 경우 '@'또는 $ observer가 필요하지 않습니다. $ watch. $ attrs를 사용할 수 있습니다. attribute_name @hugo가 암시 하듯이, 또는 숫자 나 부울을 전달하고 적절한 유형을 얻으려면 $ scope. $ eval ($ attrs. attribute_name)을 한 번 사용할 수 있습니다.

부모 범위 속성에 로컬 범위 속성을 데이터 바인딩하는 데 '='를 사용하면 속성 값을 연결 함수에서 사용할 수 있습니다 ($ observe 또는 $ watch 또는 $ eval 필요 없음).

+0

+1 이것은 나를 괴롭혔습니다. – GFoley83

+0

+1 감사합니다. –

0

당신이 지시어를 사용하여보기에 삽입하도록 지시에서이 값에 액세스하는 경우에는 $ 컴파일 API를 사용하여 각도 1.3 이후이

var string = "<div> " + scope.text + "</div>"; 
$compile(string)(scope, function(cloned, scope){ 
     element.append(cloned); 
}); 
7

처럼 뭔가를하고이 속성에 액세스 할 수 있습니다, 당신은 사용할 수 있습니다 bindToController. 여기 어떻게 사용하는지에 대한 샘플이 있습니다. 자, 내가 범위에 속성을 추가 한 다음 컨트롤러 내부에 그것을 사용하는 bindToController를 사용

var module = angular.module('testApp', []) 
    .directive('testcomponent', function() { 
    return { 
     restrict: 'E', 
     template: '<div><p>{{text}} This will run fine! </p></div>', 
     scope: { 
      text: '@text' 
     }, 
     controller: function() { 
      console.log(this.text); 
     }, 
     controllerAs: 'vm', 
     bindToController: true 
    }; 
}); 

각도 1.3은 말한다 정확하게 수행 bindToController라는 지시어 정의 객체에 새로운 속성을 소개합니다. controllerAs를 사용하는 격리 된 범위가있는 지시문에서 을 true로 설정하면 구성 요소의 속성은 범위 이 아닌 컨트롤러에 바인딩됩니다.다시 말하면, Angular는 컨트롤러가 으로 인스턴스화 될 때 격리 된 범위 바인딩의 초기 값이 이고 향후 변경 사항이 자동으로 이 될 수 있음을 의미합니다. 대신 지시를 얻을 수 $scope을 사용

+1

이것은 나를 위해 작동하지 않았다, this.text는 정의되지 않았다. – rjh

+0

@rjh이 지시어를 호출 할 때'text'를 전달 했습니까? '' – Neel

5

개인적으로 내가 link 기능의 3 매개 변수에 controller 기능 $attrs, 아니면 그냥 attrs을 사용하여 선호, 가치 속성. 내가 시간 제한없이 코드를 수행하여 controller에서 속성 값을 얻을 때 아무런 문제가 없습니다 :

var module = angular.module('testApp', []) 
    .directive('testcomponent', function() { 
    return { 
    restrict: 'E', 
    template: '<div><p>{{text}} This will run fine! </p></div>', 
    scope: { 
     text: '@text' 
    }, 
    controller: ['$scope','$attrs', function ($scope, $attrs) { 
     console.log($attrs.text); // just call to the $attrs instead $scope and i got the actual value 
     $scope.text = $attrs.text; //assign attribute to the scope 
    }] 
    }; 
}); 
관련 문제