AngularJS Directive element metodu bağlama - TypeError: 1'de 'functionName' aramak için 'in' operatörü kullanılamaz


92

Bu, ana şablonun denetleyicisidir:

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

Yönerge şu şekildedir:

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

Yönerge, ana şablonda şu şekilde uygulanır:

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

ve bu yöntem yönerge şablonundan (website-genel bakış.html) çağrılır:

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

SORU: DÜZENLE tıklandığında, konsolda şu hata belirir:

TypeError: 1'de 'editWebsite' aramak için 'in' operatörü kullanılamaz

Burada neler olduğunu bilen var mı?

Yanıtlar:


180

Bir ifade binding ( &) tanımladığınızdan , bunu idHTML'de olarak bağlamak isteyip istemediğinizi içeren bir nesne değişmez parametresiyle açıkça çağırmanız gerekir edit-website="editWebsite(id)".

Aslında, Angular'ın bunun idHTML'nizde ne olduğunu anlaması gerekir ve kapsamınızın bir parçası olmadığı için, şunları yaparak aramanıza "yerel" denilenleri eklemeniz gerekir:

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

Veya alternatif olarak:

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

Denetleyici / bağlantı kodu ile:

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

AngularJS, belgelerinde bunun bir açıklamasını içerir; "close({message: 'closing for now'})"Aşağıdaki URL ile ilgili örneğe bakın :

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


7
Cevabınız için teşekkürler ve dokümantasyondaki kesin konumu işaret ettiğiniz için, inanılmaz derecede yardımcı oldu!
Bruno Belotti

1
@floribon Bunun biraz eski olduğunu biliyorum, ancak geri aramayı yazma konusunda bir örneğiniz var mı?
tcrite

Gerçekten kullanışlı, teşekkürler.
Anurag pareek

eski projelerde çalışan kişiler için hala yararlı .. teşekkürler
BMWCMW

" Genellikle, izolat kapsamından verinin bir ifade aracılığıyla üst kapsama iletilmesi istenir; bu, yerel değişken adlarının ve değerlerinin bir eşlemesini ifade sarmalayıcı işlevine ileterek yapılabilir . Örneğin, hideDialogişlev, iletişim kutusu gizlidir. Bu, direktifte çağrılarak belirtilir close({message: 'closing for now'}). Ardından yerel değişken message, on-closeifade içinde kullanılabilir olacaktır . "[vurgu benim] Gerçek, kurgudan daha tuhaftır. Bunu olay işleyicileri için en iyi çözüm olarak nasıl seçtiklerini bilmek isterim.
39'da ruffin

7

TL; DR; - Bağlı işlevin alt bileşene aktarıldığını varsayarsınız. Bu yanlış. Aslında, AngularJS dize şablonunu ayrıştırıyor ve yeni bir işlev yaratıyor, bu da daha sonra ana işlevi çağırıyor.

Bu işlevin düz bir değişken yerine anahtarlar ve değerler içeren bir nesneyi alması gerekir.

Daha Uzun Açıklama

Bu, '&' kullanarak bir işlevi bağladığınızda ve bu işlevi denetleyicinizden çağırmaya çalıştığınızda, düz değişkenin adını içeren bir nesne yerine düz bir değişken ilettiğinizde gerçekleşir. Değerlerin bağlı işleve nasıl aktarılacağını bulmak için şablon oluşturma motoru tarafından nesne anahtarlarına ihtiyaç vardır.

Örneğin. boundFunction('cats')yerine aradınboundFunction({value: 'cats'})

Çalışılan Örnek

Şöyle bir bileşen oluşturduğumu varsayalım:

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

Bu işlev (ebeveynde) şöyle görünür:

onSearch(value) {
  // do search
}

Üst şablonumda artık şunu yapabilirim:

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

Buradaki bağlama dizeden ayrıştırılacaktır. Aslında işlevi geçmiyorsunuz. AngularJS, sizin için işlevi çağıran bir işlev yapıyor. Şablonda oluşturulan bağlama, işlev çağrısı dışında birçok şey içerebilir.

AngularJS bir şekilde nereden alınacağını bulmaya ihtiyaç duyar valueve bunu ebeveynden bir nesne alarak yapar.

MyComponent denetleyicide aşağıdaki gibi bir şey yapmam gerekiyor:

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

1
Mutlak para topu; teşekkür ederim: " Aradığınız boundFunction('cats')ziyadeboundFunction({value: 'cats'}) "
ruffin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.