AngularJS 지시문 요소 메서드 바인딩-TypeError : 'in'연산자를 사용하여 1에서 'functionName'을 검색 할 수 없습니다.


92

다음은 기본 템플릿의 컨트롤러입니다.

app.controller('OverviewCtrl', ['$scope', '$location', '$routeParams', 'websiteService', 'helperService', function($scope, $location, $routeParams, websiteService, helperService) {
    ...     
    $scope.editWebsite = function(id) {
        $location.path('/websites/edit/' + id);
    };
}]);

이것은 지시문입니다 :

app.directive('wdaWebsitesOverview', function() {
    return {
        restrict: 'E',
        scope: {
            heading: '=',
            websites: '=',
            editWebsite: '&'
        },
        templateUrl: 'views/websites-overview.html'
    }
});

다음은 지시문이 기본 템플릿에 적용되는 방법입니다.

<wda-websites-overview heading="'All websites'" websites="websites" edit-website="editWebsite(id)"></wda-websites-overview>

그리고 이것은 지시어 템플릿 (website-overview.html)에서 호출되는 메소드입니다.

<td data-ng-click="editWebsite(website.id)">EDIT</td>

질문 : 편집을 클릭하면 다음 오류가 콘솔에 나타납니다.

TypeError : 'in'연산자를 사용하여 1에서 'editWebsite'를 검색 할 수 없습니다.

여기서 무슨 일이 일어나는지 아는 사람 있나요?

답변:


180

표현식 바인딩 ( &) 을 정의 했으므로 idHTML에서 .txt로 바인딩하려는 경우 포함하는 객체 리터럴 매개 변수를 사용하여 명시 적으로 호출해야합니다 edit-website="editWebsite(id)".

실제로 Angular는 이것이 id여러분의 HTML에있는 것이 무엇인지 이해해야 하며, 그것이 여러분의 범위에 속하지 않기 때문에 다음을 수행하여 호출에 "로컬"이라고하는 것을 추가해야합니다.

data-ng-click="editWebsite({id: website.id})"

또는 대안으로 :

data-ng-click="onClick(website.id)"

컨트롤러 / 링크 코드 :

$scope.onClick = function(id) {
  // Ad "id" to the locals of "editWebsite" 
  $scope.editWebsite({id: id});
}

AngularJS는 문서에 이에 대한 설명을 포함합니다. "close({message: 'closing for now'})"다음 URL과 관련된 예를 찾으십시오 .

https://docs.angularjs.org/guide/directive


7
귀하의 답변과 문서의 정확한 위치를 지적 해 주셔서 감사합니다. 믿을 수 없을만큼 도움이되었습니다!
Bruno Belotti 2015 년

1
@floribon 나는 이것이 오래되었다는 것을 알고 있지만 콜백을 타이핑하는 예가 있습니까?
tcrite

정말 유용합니다. 감사합니다.
Anurag pareek

레거시 프로젝트에서 작업하는 사람들에게 여전히 유용합니다. 감사합니다
BMWCMW

" 종종 격리 범위의 데이터를 표현식을 통해 상위 범위로 전달하는 것이 바람직합니다. 이는 지역 변수 이름 및 값의 맵을 표현식 래퍼 함수로 전달하여 수행 할 수 있습니다 . 예를 들어, hideDialog함수는 다음과 같은 경우에 표시 할 메시지를받습니다. 대화 상자가 숨겨져 있습니다. 이것은를 호출하여 지시문에 지정됩니다 close({message: 'closing for now'}). 그러면 표현식 message내에서 지역 변수 를 사용할 수 있습니다on-close . 이벤트 핸들러를위한 최상의 솔루션으로 어떻게 선택했는지 알고 싶습니다.
ruffin

6

TL; DR; -바인딩 된 함수가 자식 구성 요소에 전달되고 있다고 가정합니다. 이것은 올바르지 않습니다. 실제로 AngularJS는 문자열 템플릿을 구문 분석하고 새 함수를 생성 한 다음 부모 함수를 호출합니다.

이 함수는 일반 변수가 아닌 키와 값이있는 객체를 받아야합니다.

더 긴 설명

이것은 '&'를 사용하여 함수를 바인딩하고 컨트롤러에서 해당 함수를 호출하여 일반 변수의 이름을 포함하는 개체가 아닌 일반 변수를 전달하려고 할 때 발생합니다. 객체 키는 바운드 함수에 값을 전달하는 방법을 알아 내기 위해 템플릿 엔진에 필요합니다.

예. 당신은 불렀다 boundFunction('cats')보다는boundFunction({value: 'cats'})

작동 예

다음과 같은 구성 요소를 생성한다고 가정합니다.

const MyComponent = {
  bindings: {
    onSearch: '&'
  },
  controller: controller
};

이 함수 (부모)는 다음과 같습니다.

onSearch(value) {
  // do search
}

이제 부모 템플릿에서 다음을 수행 할 수 있습니다.

<my-component on-search="onSearch(value)"></my-component>

여기의 바인딩은 문자열에서 구문 분석됩니다. 실제로 함수를 전달하지 않습니다. AngularJS는 함수를 호출하는 함수를 만들고 있습니다. 템플릿에서 생성 된 바인딩은 함수 호출 외에 많은 것을 포함 할 수 있습니다.

AngularJS는 어떻게 든 얻을 수있는 곳을 알아 내야하며 value, 부모로부터 객체를 받아이를 수행합니다.

myComponent 컨트롤러에서 다음과 같이해야합니다.

handleOnSearch(value) {
  if (this.onSearch) {
    this.onSearch({value: value})
  }
}

1
절대 머니 볼; 감사합니다 : " 대신 전화를 걸었 boundFunction('cats')습니다boundFunction({value: 'cats'}) "
ruffin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.