我已经创建了一个包装jQuery插件的指令,并将插件的配置对象从控制器传递给指令. (作品)
在config对象中是我想要在事件上调用的回调. (作品)
在回调中,我想修改控制器的$scope上的属性,这不起作用. Angular不承认该属性由于某种原因而发生了变化,这让我相信回调中的$scope与控制器的$scope不同.我的问题是我不知道为什么.
任何人都能指出我正确的方向吗?
app.js
var app = angular.module('app',[]) .directive('datepicker',function () { return { restrict: 'A',link: function (scope,element,attrs) { // Uncommenting the line below causes // the "date changed!" text to appear,// as I expect it would. // scope.dateChanged = true; var dateInput = angular.element('.datepicker') dateInput.datepicker(scope.datepickerOpts); // The datepicker fires a changeDate event // when a date is chosen. I want to execute the // callback defined in a controller. // --- // PROBLEM: // Angular does not recognize that $scope.dateChanged // is changed in the callback. The view does not update. dateInput.bind('changeDate',scope.onDateChange); } }; }); var myModule = angular.module('myModule',['app']) .controller('MyCtrl',['$scope',function ($scope) { $scope.dateChanged = false; $scope.datepickerOpts = { autoclose: true,format: 'mm-dd-yyyy' }; $scope.onDateChange = function () { alert('onDateChange called!'); // ------------------ // PROBLEM AREA: // This doesnt cause the "date changed!" text to show. // ------------------ $scope.dateChanged = true; setTimeout(function () { $scope.dateChanged = false; },5000); }; }]);
HTML
<div ng-controller="MyCtrl"> <p ng-show="dateChanged">date changed!</p> <input type="text" value="02-16-2012" class="datepicker" datepicker=""> </div>
您的演示中有许多范围问题.首先,在dateChange回调中,即使函数本身在控制器内声明,回调内的这个上下文也是bootstrap元素,因为它在bootstrap处理程序中.
每当您从第三方代码中更改角度范围值时,角度需要通过使用$apply来了解它.通常最好将所有第三方范围保留在指令中.
更有棱角的方法是在输入上使用ng-model.然后使用$.watch更改模型.这有助于将控制器内的所有代码保持在角度上下文中.在任何角度应用中很少使用任何表格控件上的ng-model
<input type="text" class="datepicker" datepicker="" ng-model="myDate">
在指令内:
dateInput.bind('changeDate',function(){ scope.$apply(function(){ scope[attrs.ngModel] = element.val() }); });
然后在控制器中:
$scope.$watch('myDate',function(oldVal,newVal){ if(oldVal !=newVal){ /* since this code is in angular context will work for the hide/show now*/ $scope.dateChanged=true; $timeout(function(){ $scope.dateChanged=false; },5000); } });
演示:http://jsfiddle.net/qxjck/10/
编辑如果要在页面中的多个元素上使用此指令,则应更改的另一项是remove var dateInput = angular.element(‘.datepicker’).在指令中使用它是冗余的,其中element已经是链接回调中的参数之一,并且是特定于实例的.将dateInput替换为element