控制器和控制器之间的共享范围AngularJS 中的指令 [英] Sharing scope between controller & directive in AngularJS

查看:24
本文介绍了控制器和控制器之间的共享范围AngularJS 中的指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个指令来包装一个 jQuery 插件,并且我将插件的一个配置对象从控制器传递给该指令.(作品)

在配置对象中是一个回调,我想在事件上调用它.(作品)

在回调中,我想修改控制器 $scope 上的一个属性,不起作用.Angular 无法识别出由于某种原因属性发生了变化,这让我相信回调中的 $scope 与控制器的 $scope 不同.我的问题是我不知道为什么.

有人能指出我正确的方向吗?

<小时>

点击此处查看小提琴

<小时>

app.js

var app = angular.module('app', []).directive('datepicker', function () {返回 {限制:'A',链接:函数(范围、元素、属性){//取消注释下面的行导致//日期改变了!"出现的文字,//正如我所期望的那样.//scope.dateChanged = true;var dateInput = angular.element('.datepicker')dateInput.datepicker(scope.datepickerOpts);//日期选择器触发 changeDate 事件//选择日期时.我想执行//在控制器中定义的回调.//---//问题://Angular 无法识别 $scope.dateChanged//在回调中改变.视图不会更新.dateInput.bind('changeDate', scope.onDateChange);}};});var myModule = angular.module('myModule', ['app']).controller('MyCtrl', ['$scope', function ($scope) {$scope.dateChanged = false;$scope.datepickerOpts = {自动关闭:真,格式:'mm-dd-yyyy'};$scope.onDateChange = 函数 () {alert('onDateChange 被调用了!');//------------------//问题区域://这不会导致日期更改!"要显示的文本.//------------------$scope.dateChanged = true;设置超时(函数(){$scope.dateChanged = false;}, 5000);};}]);

html

<p ng-show="dateChanged">日期已更改!</p><input type="text" value="02-16-2012" class="datepicker" datepicker="">

解决方案

在您的演示中有许多作用域问题.首先,在 dateChange 回调中,即使函数本身是在控制器中声明的,回调中 this 的上下文是引导元素,因为它在引导处理程序中.

每当您在第三方代码中更改 angular 范围值时,angular 都需要使用 $apply 来了解它.通常最好将所有第三方作用域保留在指令中.

一种更有角度的方法是在输入上使用 ng-model.然后使用 $.watch 更改模型.这有助于将控制器内的所有代码保持在角度上下文中.在任何 Angular 应用程序中都很少在任何表单控件上使用 ng-model

 

内指令:

dateInput.bind('changeDate',function(){范围.$应用(函数(){范围[attrs.ngModel] = element.val()});});

然后在控制器中:

$scope.$watch('myDate',function(oldVal,newVal){if(oldVal !=newVal){/* 因为这个代码在 angular 上下文中将适用于现在隐藏/显示*/$scope.dateChanged=true;$超时(功能(){$scope.dateChanged=false;},5000);}});

演示:http://jsfiddle.net/qxjck/10/

EDIT 如果您想在多个元素上使用此指令,则应该更改的另一项是删除 var dateInput = angular.element('.datepicker')在页面中.在指令中使用它是多余的,其中 element 已经是 link 回调中的参数之一,并且是特定于实例的.将 dateInput 替换为 element

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?


Click here for Fiddle


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆