Liên kết phương thức phần tử chỉ thị AngularJS - TypeError: Không thể sử dụng toán tử 'in' để tìm kiếm 'functionName' trong 1


90

Đây là bộ điều khiển của mẫu chính:

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

Đây là chỉ thị:

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

Đây là cách chỉ thị được áp dụng trong mẫu chính:

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

và phương thức này được gọi từ mẫu chỉ thị (website-Overview.html):

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

HỎI: Khi nhấp vào CHỈNH SỬA, lỗi này xuất hiện trong bảng điều khiển:

TypeError: Không thể sử dụng toán tử 'in' để tìm kiếm 'editWebsite' trong 1

Có ai biết những gì đang xảy ra ở đây?

Câu trả lời:


178

Vì bạn đã xác định một ràng buộc biểu thức ( &), bạn cần phải gọi nó một cách rõ ràng bằng JSON có chứa idnếu bạn muốn liên kết nó trong HTML với tư cách là edit-website="editWebsite(id)".

Thật vậy, Angular cần phải hiểu đây idlà gì trong HTML của bạn và vì nó không thuộc phạm vi của bạn, bạn cần thêm những gì được gọi là "local" vào cuộc gọi của mình bằng cách:

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

Hoặc thay thế:

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

Với bộ điều khiển / mã liên kết:

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

Điều này được ghi lại ở đây, hãy tìm ví dụ liên quan đến "close({message: 'closing for now'})"

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


7
Cảm ơn câu trả lời của bạn và đã chỉ ra vị trí chính xác trên tài liệu, điều đó thật hữu ích!
Bruno Belotti

1
@floribon Tôi biết đây là loại cũ, nhưng bạn có ví dụ về cách viết kiểu chữ gọi lại không?
tcrite

Nó thực sự hữu ích, Cảm ơn.
Anurag pareek

vẫn hữu ích cho những người làm việc trong các dự án cũ .. cảm ơn
BMWCMW

4

TL; DR; - Bạn đang giả định rằng hàm ràng buộc đang được truyền cho thành phần con. Điều này là không đúng. Trên thực tế, AngularJS đang phân tích chuỗi mẫu và tạo một hàm mới, sau đó gọi hàm cha.

Hàm này cần nhận một đối tượng có khóa và giá trị, thay vì một biến đơn giản.

Giải thích dài hơn

Điều này xảy ra khi bạn đã ràng buộc một hàm bằng cách sử dụng '&' và đã cố gắng gọi hàm đó từ bộ điều khiển của mình, truyền một biến đơn giản chứ không phải một đối tượng chứa tên của biến đơn giản. Các khóa đối tượng là cần thiết của công cụ tạo mẫu để tìm ra cách chuyển các giá trị vào hàm liên kết.

ví dụ. bạn đã gọi boundFunction('cats')hơn làboundFunction({value: 'cats'})

Ví dụ về công việc

Giả sử tôi tạo một thành phần như thế này:

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

Hàm này (trong cha) trông giống như sau:

onSearch(value) {
  // do search
}

Trong mẫu mẹ của tôi, bây giờ tôi có thể làm điều này:

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

Ràng buộc ở đây sẽ được phân tích cú pháp từ chuỗi. Bạn không thực sự chuyển chức năng. AngularJS đang tạo cho bạn một hàm gọi hàm. Liên kết được tạo trong mẫu có thể chứa nhiều thứ khác ngoài lệnh gọi hàm.

AngularJS bằng cách nào đó cần phải tìm ra nơi để lấy valuevà nó thực hiện điều này bằng cách nhận một đối tượng từ cha mẹ.

Trong bộ điều khiển myComponent, tôi cần làm điều gì đó như:

handleOnSearch(value) {
  if (this.onSearch) {
    this.onSearch({value: value})
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.