共享控制器与放大器之间的范围;指令在AngularJS [英] Sharing scope between controller & directive in AngularJS
问题描述
我创建了一个指令来包装一个jQuery插件,我通过一个配置对象从控制器的指令插件。 (作品)
在配置对象是,我想在一个事件调用回调。 (作品)
在回调,我想修改控制器的$范围属性,它的不工作的。角不承认该属性已更改出于某种原因,这使我相信,在回调$范围比控制器的$范围不同。我的问题是我不为什么。
任何人都可以点我在正确的方向?
app.js
VAR应用= angular.module(应用,[])
.directive(日期选择器,功能(){
返回{
限制:'A',
链接:功能(范围,元素,ATTRS){
//取消注释以下原因线
//日期变了!文本显示,
//我期望它。
// scope.dateChanged = TRUE; VAR dateInput = angular.element('。日期选择器) dateInput.datepicker(scope.datepickerOpts); //该日期选择器触发一个事件CHANGEDATE
//当选择的日期。我想执行
//在控制器中定义的回调。
// ---
//问题:
//角不承认$ scope.dateChanged
//回调而改变。该视图不会更新。
dateInput.bind('CHANGEDATE',scope.onDateChange);
}
};
});VAR MyModule的= angular.module('Mymodule中',['应用'])
.controller('MyCtrl',['$范围',函数($范围){
$ scope.dateChanged = FALSE; $ scope.datepickerOpts = {
autoclose:真实,
格式为:MM-DD-YYYY
}; $ scope.onDateChange =功能(){
警报('onDateChange叫!'); // ------------------
//问题区域:
//这不导致日期变了!文字显示。
// ------------------
$ scope.dateChanged =真; 的setTimeout(函数(){
$ scope.dateChanged = FALSE;
},5000);
};
}]);
HTML
< DIV NG控制器=MyCtrl>
< p NG秀=dateChanged>更改日期<!/ P>
<输入类型=文本值=2012年2月16日级=日期选择日期选择器=>
< / DIV>
在您的演示工作有许多的范围的问题。首先, dateChange
回调中,即使函数本身在控制器内声明的上下文中,这个
内回调是引导元件,因为它是一个自举处理程序中。
当你从第三方code内改变角度范围值,角度需要了解它使用 $适用
。一般最好把所有第三方的范围内的指令
一个更加棱角分明apprroach是使用 NG-模型
输入。然后使用 $。看
更改到模型。这有助于保持所有code角范围内的控制器内。在任何角度的应用程序不使用 NG-模型
在任何窗体控件
<输入类型=文本级=日期选择日期选择器=NG-模式=数值指明MyDate&GT ;
在指令:
dateInput.bind('CHANGEDATE',函数(){
范围。$应用(函数(){
范围[attrs.ngModel] = element.val()
});
});
然后在控制器:
$范围。$腕表('数值指明MyDate',函数(OLDVAL,的newval){
如果(OLDVAL!=的newval){
/ *因为这code为角上下文将用于隐藏/显示现在的工作* /
$ scope.dateChanged =真;
$超时(函数(){
$ scope.dateChanged = FALSE;
},5000);
}
});
演示: http://jsfiddle.net/qxjck/10/
修改应该改变一个多产品删除 VAR dateInput = angular.element('。日期选择器')
如果你想使用这个指令页面多个元素。它是多余的指令被用在元素
是在链接
回调已经论据之一,是特定于实例。替换 dateInput
与元素
I've created a directive to wrap a jQuery plugin, and I pass a config object for the plugin from the controller to the directive. (works)
In the config object is a callback that I want to call on an event. (works)
In the callback, I want to modify a property on the controller's $scope, which does not work. Angular does not recognize that the property has changed for some reason, which leads me to believe that the $scope in the callback is different than the controller's $scope. My problem is I just don't why.
Can anybody point me in the right direction?
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>
There are a number of scope issues at work in your demo. First , within the dateChange
callback, even though the function itself is declared inside the controller, the context of this
within the callback is the bootstrap element since it is within a bootstrap handler.
Whenever you change angular scope values from within third party code , angular needs to know about it by using $apply
. Generally best to keep all third party scopes inside the directive.
A more angular apprroach is to use ng-model
on the input. Then use $.watch
for changes to the model. This helps keep all the code inside the controller within angular context. Is rare in any angular application not to use ng-model
on any form controls
<input type="text" class="datepicker" datepicker="" ng-model="myDate">
Within directive:
dateInput.bind('changeDate',function(){
scope.$apply(function(){
scope[attrs.ngModel] = element.val()
});
});
Then in Controller:
$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);
}
});
Demo: http://jsfiddle.net/qxjck/10/
EDIT One more item that should change is remove var dateInput = angular.element('.datepicker')
if you want to use this directive on more than one element in page. It is redundant being used in directive where element
is one of the arguments in the link
callback already, and is instance specific. Replace dateInput
with element
这篇关于共享控制器与放大器之间的范围;指令在AngularJS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!