admin管理员组文章数量:1279187
I'm having a problem trying to grasp why two way data binding is't working in my custom directive?
The codez:
Directive code:
.directive('invoiceFilter', function () {
return {
restrict: 'E',
replace: true,
templateUrl: '_invoice-filter.tpl.html',
scope: {
selectedItem: '=',
selectedItemChange: '&'
},
link: function(scope) {
scope.items = {
all: 'Show all invoices',
draft: 'Show drafts only',
open: 'Show open invoices',
paid: 'Show paid invoices'
};
scope.raiseSelectedItemChange = function (key) {
alert('Selected item in directive: ' + key + " (which seems to work!)");
scope.selectedItem = key;
scope.selectedItemChange();
};
}
};
});
Directive template
<div class="btn-group dropdown">
<button class="btn dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
{{ items[selectedItem || 'open' ] }}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<li ng-repeat="(key, value) in items">
<a href="javascript:void(0)" ng-click="raiseSelectedItemChange(key)">{{ value }}</a>
</li>
</ul>
</div>
As you can see I'm just adding some data to the scope (in the link function) and relying on the behavior of ng-repeat and ng-click to raise an event/callback when an item is selected. The alert correctly displays the selected item.
But when I start using the directive like this:
HTML
<body ng-controller="MainController">
<h1>Hello Plunker!</h1>
<invoice-filter selected-item="filter" selected-item-change="filterChange()"></invoice-filter>
</body>
Controller
.controller('MainController', function($scope) {
$scope.filter = "all";
$scope.filterChange = function() {
alert("Selected item in controller: " + $scope.filter + " (does not work, databinding problem???)");
};
})
The $scope.filter value never gets updated with the item I selected in the directive, even though I specified '=' on the directive scope which to my understanding should enable two way data binding, right?
What am I missing here?
Plunk playground
Here's a plunkr with the setup described above, so you can verify that it doesn't work :o/
Thanks to anyone who can help!
I'm having a problem trying to grasp why two way data binding is't working in my custom directive?
The codez:
Directive code:
.directive('invoiceFilter', function () {
return {
restrict: 'E',
replace: true,
templateUrl: '_invoice-filter.tpl.html',
scope: {
selectedItem: '=',
selectedItemChange: '&'
},
link: function(scope) {
scope.items = {
all: 'Show all invoices',
draft: 'Show drafts only',
open: 'Show open invoices',
paid: 'Show paid invoices'
};
scope.raiseSelectedItemChange = function (key) {
alert('Selected item in directive: ' + key + " (which seems to work!)");
scope.selectedItem = key;
scope.selectedItemChange();
};
}
};
});
Directive template
<div class="btn-group dropdown">
<button class="btn dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
{{ items[selectedItem || 'open' ] }}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<li ng-repeat="(key, value) in items">
<a href="javascript:void(0)" ng-click="raiseSelectedItemChange(key)">{{ value }}</a>
</li>
</ul>
</div>
As you can see I'm just adding some data to the scope (in the link function) and relying on the behavior of ng-repeat and ng-click to raise an event/callback when an item is selected. The alert correctly displays the selected item.
But when I start using the directive like this:
HTML
<body ng-controller="MainController">
<h1>Hello Plunker!</h1>
<invoice-filter selected-item="filter" selected-item-change="filterChange()"></invoice-filter>
</body>
Controller
.controller('MainController', function($scope) {
$scope.filter = "all";
$scope.filterChange = function() {
alert("Selected item in controller: " + $scope.filter + " (does not work, databinding problem???)");
};
})
The $scope.filter value never gets updated with the item I selected in the directive, even though I specified '=' on the directive scope which to my understanding should enable two way data binding, right?
What am I missing here?
Plunk playground
Here's a plunkr with the setup described above, so you can verify that it doesn't work :o/
Thanks to anyone who can help!
Share Improve this question edited Sep 28, 2018 at 6:41 Prashant Pokhriyal 3,8374 gold badges31 silver badges41 bronze badges asked Jun 2, 2014 at 10:58 DaveDave 431 silver badge4 bronze badges2 Answers
Reset to default 10The two-way binding works, but happens on the next cycle. That's why when you reproduce it again, the value of the last cycle is shown. This is because AngularJS has no chance to run its data binding inbetween the line where you set the value and the line where you call the callback. JavaScript, in that sense, doesn't allow intervention, yet.
Changing scope.selectedItemChange();
to $timeout(scope.selectedItemChange);
is an easy fix (don't forget to inject $timeout
), by forcing the callback to be called on the next cycle.
I had implemented something similar and resolved it slightly shorter version:
just add
scope.$watch();
after
scope.selectedItem = key;
And Angular will resolve by himself how and what to do.
本文标签: javascriptAngularJSTwo Way Data Binding in a Custom Directive Not WorkingStack Overflow
版权声明:本文标题:javascript - AngularJS : Two Way Data Binding in a Custom Directive Not Working - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741283205a2370124.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论