Прив'язка методу елемента директиви AngularJS - TypeError: не вдається використовувати оператор 'in' для пошуку 'functionName' в 1


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>

ЗАПИТАННЯ. При натисканні кнопки "РЕДАКТУВАТИ" ця помилка з'являється в консолі:

Помилка TypeEr: Не вдається використовувати оператор 'in' для пошуку 'editWebsite' у 1

Хтось знає, що тут відбувається?

Відповіді:


178

Оскільки ви визначили вираз прив'язки ( &), вам потрібно явно викликати його за допомогою JSON, що містить, idякщо ви хочете прив'язати його в HTML як 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
Дякуємо за вашу відповідь і за вказівку на точне місце в документації, це було неймовірно корисно!
Бруно Белотті

1
@floribon Я знаю, що це щось старе, але чи є у вас приклад написання зворотного дзвінка?
tcrite

Це дуже корисно, дякую.
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})
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.