AngularJSディレクティブ要素のメソッドバインディング-TypeError: 'in'演算子を使用して1の 'functionName'を検索することはできません


90

これはメインテンプレートのコントローラーです。

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」を検索することはできません

ここで何が起こっているのか誰か知っていますか?

回答:


178

式バインディング(&)を定義したのでid、HTMLでとしてバインドする場合は、を含むJSONで明示的に呼び出す必要があります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});
}

これはここに文書化されています。 "close({message: 'closing for now'})"

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


7
回答ありがとうございます。また、ドキュメントの正確な場所を指摘してくれて、信じられないほど役に立ちました。
Bruno Belotti、2015

1
@floribon私はこれが古いことを知っていますが、コールバックのタイプスクリプトの例はありますか?
tcrite 2017

それは本当に便利です、ありがとう。
Anurag pareek

従来のプロジェクトに携わっている人にとってはまだ役に立ちます。ありがとう
BMWCMW

4

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})
  }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.